cloud-mu 3.2.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +1 -1
- data/ansible/roles/mu-nat/tasks/main.yml +3 -0
- data/bin/mu-adopt +12 -1
- data/bin/mu-aws-setup +41 -7
- data/bin/mu-azure-setup +34 -0
- data/bin/mu-configure +214 -119
- data/bin/mu-gcp-setup +37 -2
- data/bin/mu-load-config.rb +2 -1
- data/bin/mu-node-manage +3 -0
- data/bin/mu-refresh-ssl +67 -0
- data/bin/mu-run-tests +28 -6
- data/bin/mu-self-update +30 -10
- data/bin/mu-upload-chef-artifacts +30 -26
- data/cloud-mu.gemspec +10 -8
- data/cookbooks/mu-master/attributes/default.rb +5 -1
- data/cookbooks/mu-master/metadata.rb +2 -2
- data/cookbooks/mu-master/recipes/default.rb +81 -26
- data/cookbooks/mu-master/recipes/init.rb +197 -62
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +1 -1
- data/cookbooks/mu-master/recipes/vault.rb +78 -77
- data/cookbooks/mu-master/templates/default/mods/rewrite.conf.erb +1 -0
- data/cookbooks/mu-master/templates/default/nagios.conf.erb +103 -0
- data/cookbooks/mu-master/templates/default/web_app.conf.erb +14 -30
- data/cookbooks/mu-tools/attributes/default.rb +12 -0
- data/cookbooks/mu-tools/files/centos-6/CentOS-Base.repo +47 -0
- data/cookbooks/mu-tools/libraries/helper.rb +98 -4
- data/cookbooks/mu-tools/libraries/monkey.rb +1 -1
- data/cookbooks/mu-tools/recipes/apply_security.rb +31 -9
- data/cookbooks/mu-tools/recipes/aws_api.rb +8 -2
- data/cookbooks/mu-tools/recipes/base_repositories.rb +1 -1
- data/cookbooks/mu-tools/recipes/gcloud.rb +2 -9
- data/cookbooks/mu-tools/recipes/google_api.rb +7 -0
- data/cookbooks/mu-tools/recipes/rsyslog.rb +8 -1
- data/cookbooks/mu-tools/resources/disk.rb +113 -42
- data/cookbooks/mu-tools/resources/mommacat_request.rb +1 -2
- data/cookbooks/mu-tools/templates/centos-8/sshd_config.erb +215 -0
- data/extras/Gemfile.lock.bootstrap +394 -0
- data/extras/bucketstubs/error.html +0 -0
- data/extras/bucketstubs/index.html +0 -0
- data/extras/clean-stock-amis +11 -3
- data/extras/generate-stock-images +6 -3
- data/extras/git_rpm/build.sh +20 -0
- data/extras/git_rpm/mugit.spec +53 -0
- data/extras/image-generators/AWS/centos7.yaml +19 -16
- data/extras/image-generators/AWS/{rhel7.yaml → rhel71.yaml} +0 -0
- data/extras/image-generators/AWS/{win2k12.yaml → win2k12r2.yaml} +0 -0
- data/extras/image-generators/VMWare/centos8.yaml +15 -0
- data/extras/openssl_rpm/build.sh +19 -0
- data/extras/openssl_rpm/mussl.spec +46 -0
- data/extras/python_rpm/muthon.spec +14 -4
- data/extras/ruby_rpm/muby.spec +9 -5
- data/extras/sqlite_rpm/build.sh +19 -0
- data/extras/sqlite_rpm/muqlite.spec +47 -0
- data/install/installer +7 -5
- data/modules/mommacat.ru +2 -2
- data/modules/mu.rb +14 -7
- data/modules/mu/adoption.rb +5 -5
- data/modules/mu/cleanup.rb +47 -25
- data/modules/mu/cloud.rb +29 -1
- data/modules/mu/cloud/dnszone.rb +0 -2
- data/modules/mu/cloud/machine_images.rb +1 -1
- data/modules/mu/cloud/providers.rb +6 -1
- data/modules/mu/cloud/resource_base.rb +16 -7
- data/modules/mu/cloud/ssh_sessions.rb +5 -1
- data/modules/mu/cloud/wrappers.rb +20 -7
- data/modules/mu/config.rb +28 -12
- data/modules/mu/config/bucket.rb +31 -2
- data/modules/mu/config/cache_cluster.rb +1 -1
- data/modules/mu/config/cdn.rb +100 -0
- data/modules/mu/config/container_cluster.rb +1 -1
- data/modules/mu/config/database.rb +3 -3
- data/modules/mu/config/dnszone.rb +4 -3
- data/modules/mu/config/endpoint.rb +1 -0
- data/modules/mu/config/firewall_rule.rb +1 -1
- data/modules/mu/config/function.rb +16 -7
- data/modules/mu/config/job.rb +89 -0
- data/modules/mu/config/notifier.rb +7 -18
- data/modules/mu/config/ref.rb +55 -9
- data/modules/mu/config/schema_helpers.rb +12 -3
- data/modules/mu/config/server.rb +11 -5
- data/modules/mu/config/server_pool.rb +2 -2
- data/modules/mu/config/vpc.rb +11 -10
- data/modules/mu/defaults/AWS.yaml +106 -106
- data/modules/mu/deploy.rb +40 -14
- data/modules/mu/groomers/chef.rb +2 -2
- data/modules/mu/master.rb +70 -3
- data/modules/mu/mommacat.rb +28 -9
- data/modules/mu/mommacat/daemon.rb +13 -7
- data/modules/mu/mommacat/naming.rb +2 -2
- data/modules/mu/mommacat/search.rb +16 -5
- data/modules/mu/mommacat/storage.rb +67 -32
- data/modules/mu/providers/aws.rb +298 -85
- data/modules/mu/providers/aws/alarm.rb +5 -5
- data/modules/mu/providers/aws/bucket.rb +284 -50
- data/modules/mu/providers/aws/cache_cluster.rb +26 -26
- data/modules/mu/providers/aws/cdn.rb +782 -0
- data/modules/mu/providers/aws/collection.rb +16 -16
- data/modules/mu/providers/aws/container_cluster.rb +84 -64
- data/modules/mu/providers/aws/database.rb +59 -55
- data/modules/mu/providers/aws/dnszone.rb +29 -12
- data/modules/mu/providers/aws/endpoint.rb +535 -50
- data/modules/mu/providers/aws/firewall_rule.rb +32 -26
- data/modules/mu/providers/aws/folder.rb +1 -1
- data/modules/mu/providers/aws/function.rb +300 -134
- data/modules/mu/providers/aws/group.rb +16 -14
- data/modules/mu/providers/aws/habitat.rb +4 -4
- data/modules/mu/providers/aws/job.rb +469 -0
- data/modules/mu/providers/aws/loadbalancer.rb +67 -45
- data/modules/mu/providers/aws/log.rb +17 -17
- data/modules/mu/providers/aws/msg_queue.rb +22 -13
- data/modules/mu/providers/aws/nosqldb.rb +99 -8
- data/modules/mu/providers/aws/notifier.rb +137 -65
- data/modules/mu/providers/aws/role.rb +119 -83
- data/modules/mu/providers/aws/search_domain.rb +166 -30
- data/modules/mu/providers/aws/server.rb +209 -118
- data/modules/mu/providers/aws/server_pool.rb +95 -130
- data/modules/mu/providers/aws/storage_pool.rb +19 -11
- data/modules/mu/providers/aws/user.rb +5 -5
- data/modules/mu/providers/aws/userdata/linux.erb +5 -4
- data/modules/mu/providers/aws/vpc.rb +109 -54
- data/modules/mu/providers/aws/vpc_subnet.rb +43 -39
- data/modules/mu/providers/azure.rb +78 -12
- data/modules/mu/providers/azure/server.rb +20 -4
- data/modules/mu/providers/cloudformation/server.rb +1 -1
- data/modules/mu/providers/google.rb +21 -5
- data/modules/mu/providers/google/bucket.rb +1 -1
- data/modules/mu/providers/google/container_cluster.rb +1 -1
- data/modules/mu/providers/google/database.rb +1 -1
- data/modules/mu/providers/google/firewall_rule.rb +1 -1
- data/modules/mu/providers/google/folder.rb +7 -3
- data/modules/mu/providers/google/function.rb +66 -31
- data/modules/mu/providers/google/group.rb +1 -1
- data/modules/mu/providers/google/habitat.rb +1 -1
- data/modules/mu/providers/google/loadbalancer.rb +1 -1
- data/modules/mu/providers/google/role.rb +6 -3
- data/modules/mu/providers/google/server.rb +1 -1
- data/modules/mu/providers/google/server_pool.rb +1 -1
- data/modules/mu/providers/google/user.rb +1 -1
- data/modules/mu/providers/google/vpc.rb +28 -3
- data/modules/tests/aws-jobs-functions.yaml +46 -0
- data/modules/tests/aws-servers-with-handrolled-iam.yaml +37 -0
- data/modules/tests/centos6.yaml +4 -0
- data/modules/tests/centos7.yaml +4 -0
- data/modules/tests/ecs.yaml +2 -2
- data/modules/tests/eks.yaml +1 -1
- data/modules/tests/functions/node-function/lambda_function.js +10 -0
- data/modules/tests/functions/python-function/lambda_function.py +12 -0
- data/modules/tests/k8s.yaml +1 -1
- data/modules/tests/microservice_app.yaml +288 -0
- data/modules/tests/rds.yaml +5 -5
- data/modules/tests/regrooms/rds.yaml +5 -5
- data/modules/tests/server-with-scrub-muisms.yaml +1 -1
- data/modules/tests/super_complex_bok.yml +2 -2
- data/modules/tests/super_simple_bok.yml +2 -2
- metadata +42 -17
|
@@ -30,7 +30,7 @@ module MU
|
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
|
-
@mu_name ||= @deploy.getResourceName(@config["name"])
|
|
33
|
+
@mu_name ||= @config['scrub_mu_isms'] ? @config['name'] : @deploy.getResourceName(@config["name"], max_length: 64)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
# Called automatically by {MU::Deploy#createResources}
|
|
@@ -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
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
46
|
+
MU::Cloud::AWS.iam(credentials: @credentials).create_policy(
|
|
47
47
|
policy_name: policy_name,
|
|
48
48
|
path: "/"+@deploy.deploy_id+"/",
|
|
49
49
|
policy_document: JSON.generate(policy.values.first),
|
|
@@ -53,16 +53,18 @@ module MU
|
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
if !@config['bare_policies']
|
|
56
|
-
MU.log "Creating IAM role #{@mu_name}"
|
|
57
56
|
@cloud_id = @mu_name
|
|
58
57
|
path = @config['strip_path'] ? nil : "/"+@deploy.deploy_id+"/"
|
|
59
|
-
|
|
60
|
-
path
|
|
61
|
-
role_name
|
|
62
|
-
description
|
|
63
|
-
assume_role_policy_document
|
|
64
|
-
tags
|
|
65
|
-
|
|
58
|
+
params = {
|
|
59
|
+
:path => path,
|
|
60
|
+
:role_name => @mu_name,
|
|
61
|
+
:description => "Generated by Mu",
|
|
62
|
+
:assume_role_policy_document => gen_assume_role_policy_doc,
|
|
63
|
+
:tags => get_tag_params(@config['scrub_mu_isms'])
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
MU.log "Creating IAM role #{@mu_name} (#{@credentials})", details: params
|
|
67
|
+
MU::Cloud::AWS.iam(credentials: @credentials).create_role(params)
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
|
|
@@ -75,7 +77,7 @@ module MU
|
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
if !@config['bare_policies']
|
|
78
|
-
resp = MU::Cloud::AWS.iam(credentials: @
|
|
80
|
+
resp = MU::Cloud::AWS.iam(credentials: @credentials).get_role(
|
|
79
81
|
role_name: @mu_name
|
|
80
82
|
).role
|
|
81
83
|
ext_tags = resp.tags.map { |t| t.to_h }
|
|
@@ -84,7 +86,7 @@ module MU
|
|
|
84
86
|
|
|
85
87
|
if tag_param.size > 0
|
|
86
88
|
MU.log "Updating tags on IAM role #{@mu_name}", MU::NOTICE, details: tag_param
|
|
87
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
89
|
+
MU::Cloud::AWS.iam(credentials: @credentials).tag_role(role_name: @mu_name, tags: tag_param)
|
|
88
90
|
end
|
|
89
91
|
end
|
|
90
92
|
|
|
@@ -92,13 +94,14 @@ module MU
|
|
|
92
94
|
configured_policies = []
|
|
93
95
|
|
|
94
96
|
if @config['raw_policies']
|
|
97
|
+
MU.log "Attaching #{@config['raw_policies'].size.to_s} raw #{@config['raw_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
|
|
95
98
|
configured_policies = @config['raw_policies'].map { |p|
|
|
96
99
|
@mu_name+"-"+p.keys.first.upcase
|
|
97
100
|
}
|
|
98
101
|
end
|
|
99
102
|
|
|
100
103
|
if @config['attachable_policies']
|
|
101
|
-
MU.log "Attaching #{@config['attachable_policies'].size.to_s} #{@config['attachable_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
|
|
104
|
+
MU.log "Attaching #{@config['attachable_policies'].size.to_s} external #{@config['attachable_policies'].size > 1 ? "policies" : "policy"} to role #{@mu_name}", MU::NOTICE
|
|
102
105
|
configured_policies.concat(@config['attachable_policies'].map { |p|
|
|
103
106
|
id = if p.is_a?(MU::Config::Ref)
|
|
104
107
|
p.cloud_id
|
|
@@ -109,18 +112,17 @@ module MU
|
|
|
109
112
|
end
|
|
110
113
|
id.gsub(/.*?\/([^:\/]+)$/, '\1')
|
|
111
114
|
})
|
|
112
|
-
configured_policies.each { |pol|
|
|
113
|
-
}
|
|
114
115
|
end
|
|
115
116
|
|
|
117
|
+
# Purge anything that doesn't belong
|
|
116
118
|
if !@config['bare_policies']
|
|
117
|
-
attached_policies = MU::Cloud::AWS.iam(credentials: @
|
|
119
|
+
attached_policies = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_role_policies(
|
|
118
120
|
role_name: @mu_name
|
|
119
121
|
).attached_policies
|
|
120
122
|
attached_policies.each { |a|
|
|
121
123
|
if !configured_policies.include?(a.policy_name)
|
|
122
|
-
MU.log "Removing IAM policy #{a.policy_name} from role #{@mu_name}", MU::NOTICE
|
|
123
|
-
MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @
|
|
124
|
+
MU.log "Removing IAM policy #{a.policy_name} from role #{@mu_name}", MU::NOTICE, details: configured_policies
|
|
125
|
+
MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @credentials)
|
|
124
126
|
end
|
|
125
127
|
}
|
|
126
128
|
end
|
|
@@ -153,8 +155,8 @@ module MU
|
|
|
153
155
|
policy.values.each { |p|
|
|
154
156
|
p["Version"] ||= "2012-10-17"
|
|
155
157
|
}
|
|
156
|
-
policy_name = basename+"-"+policy.keys.first.upcase
|
|
157
158
|
|
|
159
|
+
policy_name = basename+"-"+policy.keys.first.upcase
|
|
158
160
|
arn = "arn:"+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+":iam::"+MU::Cloud::AWS.credToAcct(credentials)+":policy#{path}/#{policy_name}"
|
|
159
161
|
resp = begin
|
|
160
162
|
desc = MU::Cloud::AWS.iam(credentials: credentials).get_policy(policy_arn: arn)
|
|
@@ -164,7 +166,7 @@ module MU
|
|
|
164
166
|
version_id: desc.policy.default_version_id
|
|
165
167
|
)
|
|
166
168
|
|
|
167
|
-
ext = JSON.parse(
|
|
169
|
+
ext = JSON.parse(CGI.unescape(version.policy_version.document))
|
|
168
170
|
if ext != policy.values.first
|
|
169
171
|
# Special exception- we don't want to overwrite extra rules
|
|
170
172
|
# in MuSecrets policies, because our siblings might have
|
|
@@ -184,12 +186,16 @@ module MU
|
|
|
184
186
|
|
|
185
187
|
rescue Aws::IAM::Errors::NoSuchEntity
|
|
186
188
|
MU.log "Creating IAM policy #{policy_name}", details: policy.values.first
|
|
187
|
-
MU::Cloud::AWS.iam(credentials: credentials).create_policy(
|
|
189
|
+
desc = MU::Cloud::AWS.iam(credentials: credentials).create_policy(
|
|
188
190
|
policy_name: policy_name,
|
|
189
191
|
path: path+"/",
|
|
190
192
|
policy_document: JSON.generate(policy.values.first),
|
|
191
193
|
description: "Raw policy from #{basename}"
|
|
192
194
|
)
|
|
195
|
+
MU.retrier([Aws::IAM::Errors::NoSuchEntity], loop_if: Proc.new { desc.nil? }) {
|
|
196
|
+
desc = MU::Cloud::AWS.iam(credentials: credentials).get_policy(policy_arn: arn)
|
|
197
|
+
}
|
|
198
|
+
desc
|
|
193
199
|
end
|
|
194
200
|
arns << resp.policy.arn
|
|
195
201
|
}
|
|
@@ -216,7 +222,23 @@ module MU
|
|
|
216
222
|
# populated with one or both depending on what this resource has
|
|
217
223
|
# defined.
|
|
218
224
|
def cloud_desc(use_cache: true)
|
|
219
|
-
|
|
225
|
+
require 'aws-sdk-iam'
|
|
226
|
+
|
|
227
|
+
# we might inherit a naive cached description from the base cloud
|
|
228
|
+
# layer; rearrange it to our tastes
|
|
229
|
+
if @cloud_desc_cache.is_a?(::Aws::IAM::Types::Role)
|
|
230
|
+
new_desc = {
|
|
231
|
+
"role" => @cloud_desc_cache
|
|
232
|
+
}
|
|
233
|
+
@cloud_desc_cache = new_desc
|
|
234
|
+
elsif @cloud_desc_cache.is_a?(::Aws::IAM::Types::Policy)
|
|
235
|
+
new_desc = {
|
|
236
|
+
"policies" => [@cloud_desc_cache]
|
|
237
|
+
}
|
|
238
|
+
@cloud_desc_cache = new_desc
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
return @cloud_desc_cache if @cloud_desc_cache and !@cloud_desc_cache.empty? and use_cache
|
|
220
242
|
|
|
221
243
|
@cloud_desc_cache = {}
|
|
222
244
|
if @config['bare_policies']
|
|
@@ -290,8 +312,8 @@ end
|
|
|
290
312
|
# Insert a new target entity into an existing policy.
|
|
291
313
|
# @param policy [String]: The name of the policy to which we're appending, which must already exist as part of this role resource
|
|
292
314
|
# @param targets [Array<String>]: The target resource. If +target_type+ isn't specified, this should be a fully-resolved ARN.
|
|
293
|
-
def injectPolicyTargets(policy, targets)
|
|
294
|
-
if !policy.match(/^#{@deploy.deploy_id}/)
|
|
315
|
+
def injectPolicyTargets(policy, targets, attach: false)
|
|
316
|
+
if @deploy and !policy.match(/^#{@deploy.deploy_id}/)
|
|
295
317
|
policy = @mu_name+"-"+policy.upcase
|
|
296
318
|
end
|
|
297
319
|
my_policies = cloud_desc(use_cache: false)["policies"]
|
|
@@ -301,19 +323,19 @@ end
|
|
|
301
323
|
my_policies.each { |p|
|
|
302
324
|
if p.policy_name == policy
|
|
303
325
|
seen_policy = true
|
|
304
|
-
old = MU::Cloud::AWS.iam(credentials: @
|
|
326
|
+
old = MU::Cloud::AWS.iam(credentials: @credentials).get_policy_version(
|
|
305
327
|
policy_arn: p.arn,
|
|
306
328
|
version_id: p.default_version_id
|
|
307
329
|
).policy_version
|
|
308
330
|
|
|
309
|
-
doc = JSON.parse
|
|
331
|
+
doc = JSON.parse CGI.unescape_www_form_component old.document
|
|
310
332
|
need_update = false
|
|
311
333
|
|
|
312
334
|
doc["Statement"].each { |s|
|
|
313
335
|
targets.each { |target|
|
|
314
336
|
target_string = target
|
|
315
337
|
|
|
316
|
-
if target['type']
|
|
338
|
+
if target['type'] and @deploy
|
|
317
339
|
sibling = @deploy.findLitterMate(
|
|
318
340
|
name: target["identifier"],
|
|
319
341
|
type: target["type"]
|
|
@@ -419,14 +441,14 @@ end
|
|
|
419
441
|
# @param noop [Boolean]: If true, will only print what would be done
|
|
420
442
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
|
421
443
|
# @return [void]
|
|
422
|
-
def self.cleanup(noop: false, ignoremaster: false, credentials: nil, flags: {})
|
|
444
|
+
def self.cleanup(noop: false, deploy_id: MU.deploy_id, ignoremaster: false, credentials: nil, flags: {})
|
|
423
445
|
|
|
424
446
|
resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
|
|
425
|
-
path_prefix: "/"+
|
|
447
|
+
path_prefix: "/"+deploy_id+"/"
|
|
426
448
|
)
|
|
427
449
|
if resp and resp.policies
|
|
428
450
|
resp.policies.each { |policy|
|
|
429
|
-
MU.log "Deleting IAM policy /#{
|
|
451
|
+
MU.log "Deleting IAM policy /#{deploy_id}/#{policy.policy_name}"
|
|
430
452
|
if !noop
|
|
431
453
|
purgePolicy(policy.arn, credentials)
|
|
432
454
|
end
|
|
@@ -437,19 +459,23 @@ end
|
|
|
437
459
|
roles = MU::Cloud::AWS::Role.find(credentials: credentials).values
|
|
438
460
|
roles.each { |r|
|
|
439
461
|
next if !r.respond_to?(:role_name)
|
|
440
|
-
if r.path.match(/^\/#{Regexp.quote(
|
|
462
|
+
if r.path.match(/^\/#{Regexp.quote(deploy_id)}/)
|
|
441
463
|
deleteme << r
|
|
442
464
|
next
|
|
443
465
|
end
|
|
444
466
|
# For some dumb reason, the list output that .find gets doesn't
|
|
445
467
|
# include the tags, so we need to fetch each role individually to
|
|
446
468
|
# check tags. Hardly seems efficient.
|
|
447
|
-
desc =
|
|
469
|
+
desc = begin
|
|
470
|
+
MU::Cloud::AWS.iam(credentials: credentials).get_role(role_name: r.role_name)
|
|
471
|
+
rescue Aws::IAM::Errors::NoSuchEntity
|
|
472
|
+
next
|
|
473
|
+
end
|
|
448
474
|
if desc.role and desc.role.tags and desc.role.tags
|
|
449
475
|
master_match = false
|
|
450
476
|
deploy_match = false
|
|
451
477
|
desc.role.tags.each { |t|
|
|
452
|
-
if t.key == "MU-ID" and t.value ==
|
|
478
|
+
if t.key == "MU-ID" and t.value == deploy_id
|
|
453
479
|
deploy_match = true
|
|
454
480
|
elsif t.key == "MU-MASTER-IP" and t.value == MU.mu_public_ip
|
|
455
481
|
master_match = true
|
|
@@ -516,7 +542,7 @@ end
|
|
|
516
542
|
|
|
517
543
|
begin
|
|
518
544
|
# managed policies get fetched by ARN, roles by plain name. Ok!
|
|
519
|
-
if args[:cloud_id].match(/^arn
|
|
545
|
+
if args[:cloud_id].match(/^arn:.*?:policy\//)
|
|
520
546
|
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).get_policy(
|
|
521
547
|
policy_arn: args[:cloud_id]
|
|
522
548
|
)
|
|
@@ -525,39 +551,26 @@ end
|
|
|
525
551
|
end
|
|
526
552
|
else
|
|
527
553
|
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).get_role(
|
|
528
|
-
role_name: args[:cloud_id]
|
|
554
|
+
role_name: args[:cloud_id].sub(/^arn:.*?\/([^:\/]+)$/, '\1') # XXX if it's an ARN, actually parse it and look in the correct account when applicable
|
|
529
555
|
)
|
|
556
|
+
|
|
530
557
|
if resp and resp.role
|
|
531
|
-
found[
|
|
558
|
+
found[resp.role.role_name] = resp.role
|
|
532
559
|
end
|
|
533
560
|
end
|
|
534
561
|
rescue ::Aws::IAM::Errors::NoSuchEntity
|
|
535
562
|
end
|
|
536
563
|
|
|
537
564
|
else
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
)
|
|
543
|
-
break if !resp or !resp.roles
|
|
544
|
-
resp.roles.each { |role|
|
|
545
|
-
found[role.role_name] = role
|
|
546
|
-
}
|
|
547
|
-
marker = resp.marker
|
|
548
|
-
end while marker
|
|
565
|
+
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).list_roles
|
|
566
|
+
resp.roles.each { |role|
|
|
567
|
+
found[role.role_name] = role
|
|
568
|
+
}
|
|
549
569
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
)
|
|
555
|
-
break if !resp or !resp.policies
|
|
556
|
-
resp.policies.each { |pol|
|
|
557
|
-
found[pol.arn] = pol
|
|
558
|
-
}
|
|
559
|
-
marker = resp.marker
|
|
560
|
-
end while marker
|
|
570
|
+
resp = MU::Cloud::AWS.iam(credentials: args[:credentials]).list_policies(scope: "Local")
|
|
571
|
+
resp.policies.each { |pol|
|
|
572
|
+
found[pol.arn] = pol
|
|
573
|
+
}
|
|
561
574
|
end
|
|
562
575
|
|
|
563
576
|
found
|
|
@@ -569,7 +582,7 @@ end
|
|
|
569
582
|
def toKitten(**_args)
|
|
570
583
|
bok = {
|
|
571
584
|
"cloud" => "AWS",
|
|
572
|
-
"credentials" => @
|
|
585
|
+
"credentials" => @credentials,
|
|
573
586
|
"cloud_id" => @cloud_id
|
|
574
587
|
}
|
|
575
588
|
|
|
@@ -603,7 +616,7 @@ end
|
|
|
603
616
|
policy_name: pol.policy_name
|
|
604
617
|
)
|
|
605
618
|
if resp and resp.policy_document
|
|
606
|
-
JSON.parse(
|
|
619
|
+
JSON.parse(CGI.unescape(resp.policy_document))
|
|
607
620
|
end
|
|
608
621
|
rescue ::Aws::IAM::Errors::NoSuchEntity, ::Aws::IAM::Errors::ValidationError
|
|
609
622
|
resp = MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
|
|
@@ -613,7 +626,7 @@ end
|
|
|
613
626
|
policy_arn: pol.arn,
|
|
614
627
|
version_id: resp.policy.default_version_id
|
|
615
628
|
)
|
|
616
|
-
JSON.parse(
|
|
629
|
+
JSON.parse(CGI.unescape(version.policy_version.document))
|
|
617
630
|
end
|
|
618
631
|
bok["policies"] = MU::Cloud::AWS::Role.doc2MuPolicies(pol.policy_name, doc, bok["policies"])
|
|
619
632
|
end
|
|
@@ -629,7 +642,7 @@ end
|
|
|
629
642
|
bok["strip_path"] = true if desc.path == "/"
|
|
630
643
|
|
|
631
644
|
if desc.assume_role_policy_document
|
|
632
|
-
assume_doc = JSON.parse(
|
|
645
|
+
assume_doc = JSON.parse(CGI.unescape(desc.assume_role_policy_document))
|
|
633
646
|
assume_doc["Statement"].each { |s|
|
|
634
647
|
bok["can_assume"] ||= []
|
|
635
648
|
method = if s["Action"] == "sts:AssumeRoleWithWebIdentity"
|
|
@@ -762,12 +775,12 @@ end
|
|
|
762
775
|
def bindTo(entitytype, entityname)
|
|
763
776
|
if entitytype == "instance_profile"
|
|
764
777
|
begin
|
|
765
|
-
resp = MU::Cloud::AWS.iam(credentials: @
|
|
778
|
+
resp = MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(
|
|
766
779
|
instance_profile_name: entityname
|
|
767
780
|
).instance_profile
|
|
768
781
|
|
|
769
782
|
if !resp.roles.map { |r| r.role_name}.include?(@mu_name)
|
|
770
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
783
|
+
MU::Cloud::AWS.iam(credentials: @credentials).add_role_to_instance_profile(
|
|
771
784
|
instance_profile_name: entityname,
|
|
772
785
|
role_name: @mu_name
|
|
773
786
|
)
|
|
@@ -777,30 +790,30 @@ end
|
|
|
777
790
|
raise e
|
|
778
791
|
end
|
|
779
792
|
elsif ["user", "group", "role"].include?(entitytype)
|
|
780
|
-
mypolicies = MU::Cloud::AWS.iam(credentials: @
|
|
793
|
+
mypolicies = MU::Cloud::AWS.iam(credentials: @credentials).list_policies(
|
|
781
794
|
path_prefix: "/"+@deploy.deploy_id+"/"
|
|
782
795
|
).policies
|
|
783
796
|
mypolicies.reject! { |p|
|
|
784
|
-
!p.policy_name.match(/^#{Regexp.quote(@mu_name)}
|
|
797
|
+
!p.policy_name.match(/^#{Regexp.quote(@mu_name)}(-|$)/)
|
|
785
798
|
}
|
|
786
799
|
|
|
787
800
|
if @config['attachable_policies']
|
|
788
801
|
@config['attachable_policies'].each { |policy_hash|
|
|
789
802
|
policy = policy_hash["id"]
|
|
790
803
|
p_arn = if !policy.match(/^arn:/i)
|
|
791
|
-
"arn:"+(MU::Cloud::AWS.isGovCloud?(@
|
|
804
|
+
"arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":iam::aws:policy/"+policy
|
|
792
805
|
else
|
|
793
806
|
policy
|
|
794
807
|
end
|
|
795
808
|
|
|
796
809
|
subpaths = ["service-role", "aws-service-role", "job-function"]
|
|
797
810
|
begin
|
|
798
|
-
mypolicies << MU::Cloud::AWS.iam(credentials: @
|
|
811
|
+
mypolicies << MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
|
|
799
812
|
policy_arn: p_arn
|
|
800
813
|
).policy
|
|
801
814
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
|
802
815
|
if subpaths.size > 0
|
|
803
|
-
p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@
|
|
816
|
+
p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@region) ? "aws-us-gov" : "aws")+":iam::aws:policy/#{subpaths.shift}/"+policy
|
|
804
817
|
retry
|
|
805
818
|
end
|
|
806
819
|
raise e
|
|
@@ -808,39 +821,52 @@ end
|
|
|
808
821
|
}
|
|
809
822
|
end
|
|
810
823
|
|
|
824
|
+
if @config['raw_policies']
|
|
825
|
+
raw_arns = MU::Cloud::AWS::Role.manageRawPolicies(
|
|
826
|
+
@config['raw_policies'],
|
|
827
|
+
basename: @deploy.getResourceName(@config['name']),
|
|
828
|
+
credentials: @credentials
|
|
829
|
+
)
|
|
830
|
+
raw_arns.each { |p_arn|
|
|
831
|
+
mypolicies << MU::Cloud::AWS.iam(credentials: @credentials).get_policy(
|
|
832
|
+
policy_arn: p_arn
|
|
833
|
+
).policy
|
|
834
|
+
}
|
|
835
|
+
end
|
|
836
|
+
|
|
811
837
|
mypolicies.each { |p|
|
|
812
838
|
if entitytype == "user"
|
|
813
|
-
resp = MU::Cloud::AWS.iam(credentials: @
|
|
839
|
+
resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_user_policies(
|
|
814
840
|
path_prefix: "/"+@deploy.deploy_id+"/",
|
|
815
841
|
user_name: entityname
|
|
816
842
|
)
|
|
817
843
|
if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
|
|
818
844
|
MU.log "Attaching IAM policy #{p.policy_name} to user #{entityname}", MU::NOTICE
|
|
819
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
845
|
+
MU::Cloud::AWS.iam(credentials: @credentials).attach_user_policy(
|
|
820
846
|
policy_arn: p.arn,
|
|
821
847
|
user_name: entityname
|
|
822
848
|
)
|
|
823
849
|
end
|
|
824
850
|
elsif entitytype == "group"
|
|
825
|
-
resp = MU::Cloud::AWS.iam(credentials: @
|
|
851
|
+
resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_group_policies(
|
|
826
852
|
path_prefix: "/"+@deploy.deploy_id+"/",
|
|
827
853
|
group_name: entityname
|
|
828
854
|
)
|
|
829
855
|
if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
|
|
830
856
|
MU.log "Attaching policy #{p.policy_name} to group #{entityname}", MU::NOTICE
|
|
831
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
857
|
+
MU::Cloud::AWS.iam(credentials: @credentials).attach_group_policy(
|
|
832
858
|
policy_arn: p.arn,
|
|
833
859
|
group_name: entityname
|
|
834
860
|
)
|
|
835
861
|
end
|
|
836
862
|
elsif entitytype == "role"
|
|
837
|
-
resp = MU::Cloud::AWS.iam(credentials: @
|
|
863
|
+
resp = MU::Cloud::AWS.iam(credentials: @credentials).list_attached_role_policies(
|
|
838
864
|
role_name: entityname
|
|
839
865
|
)
|
|
840
866
|
|
|
841
867
|
if !resp or !resp.attached_policies.map { |a_p| a_p.policy_name }.include?(p.policy_name)
|
|
842
868
|
MU.log "Attaching policy #{p.policy_name} to role #{entityname}", MU::NOTICE
|
|
843
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
869
|
+
MU::Cloud::AWS.iam(credentials: @credentials).attach_role_policy(
|
|
844
870
|
policy_arn: p.arn,
|
|
845
871
|
role_name: entityname
|
|
846
872
|
)
|
|
@@ -861,19 +887,19 @@ end
|
|
|
861
887
|
end
|
|
862
888
|
|
|
863
889
|
resp = begin
|
|
864
|
-
MU.log "Creating instance profile #{@mu_name} #{@
|
|
865
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
890
|
+
MU.log "Creating instance profile #{@mu_name} #{@credentials}"
|
|
891
|
+
MU::Cloud::AWS.iam(credentials: @credentials).create_instance_profile(
|
|
866
892
|
instance_profile_name: @mu_name
|
|
867
893
|
)
|
|
868
894
|
rescue Aws::IAM::Errors::EntityAlreadyExists
|
|
869
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
895
|
+
MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(
|
|
870
896
|
instance_profile_name: @mu_name
|
|
871
897
|
)
|
|
872
898
|
end
|
|
873
899
|
|
|
874
900
|
# make sure it's really there before moving on
|
|
875
901
|
begin
|
|
876
|
-
MU::Cloud::AWS.iam(credentials: @
|
|
902
|
+
MU::Cloud::AWS.iam(credentials: @credentials).get_instance_profile(instance_profile_name: @mu_name)
|
|
877
903
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
|
878
904
|
MU.log e.inspect, MU::WARN
|
|
879
905
|
sleep 10
|
|
@@ -1061,6 +1087,8 @@ end
|
|
|
1061
1087
|
role.delete("import")
|
|
1062
1088
|
end
|
|
1063
1089
|
|
|
1090
|
+
role['strip_path'] = true if role['scrub_mu_isms']
|
|
1091
|
+
|
|
1064
1092
|
# If we're attaching some managed policies, make sure all of the ones
|
|
1065
1093
|
# that should already exist do indeed exist
|
|
1066
1094
|
if role['attachable_policies']
|
|
@@ -1091,7 +1119,7 @@ end
|
|
|
1091
1119
|
role['policies'].each { |policy|
|
|
1092
1120
|
policy['targets'].each { |target|
|
|
1093
1121
|
if target['type']
|
|
1094
|
-
MU::Config.addDependency(role, target['identifier'], target['type'])
|
|
1122
|
+
MU::Config.addDependency(role, target['identifier'], target['type'], my_phase: "groom")
|
|
1095
1123
|
end
|
|
1096
1124
|
}
|
|
1097
1125
|
}
|
|
@@ -1107,13 +1135,14 @@ end
|
|
|
1107
1135
|
# @param policies [Array<Hash>]: One or more policy chunks
|
|
1108
1136
|
# @param deploy_obj [MU::MommaCat]: Deployment object to use when looking up sibling Mu resources
|
|
1109
1137
|
# @return [Array<Hash>]
|
|
1110
|
-
def self.genPolicyDocument(policies, deploy_obj: nil, bucket_style: false)
|
|
1138
|
+
def self.genPolicyDocument(policies, deploy_obj: nil, bucket_style: false, version: "2012-10-17", doc_id: nil)
|
|
1111
1139
|
if policies
|
|
1112
1140
|
name = nil
|
|
1113
1141
|
doc = {
|
|
1114
|
-
"Version" =>
|
|
1142
|
+
"Version" => version,
|
|
1115
1143
|
"Statement" => []
|
|
1116
1144
|
}
|
|
1145
|
+
doc["Id"] = doc_id if doc_id
|
|
1117
1146
|
policies.each { |policy|
|
|
1118
1147
|
policy["flag"] ||= "Allow"
|
|
1119
1148
|
statement = {
|
|
@@ -1154,7 +1183,14 @@ end
|
|
|
1154
1183
|
raise MuError, "Couldn't find a #{grantee["type"]} named #{grantee["identifier"]} when generating IAM policy"
|
|
1155
1184
|
end
|
|
1156
1185
|
else
|
|
1157
|
-
bucket_prefix = grantee["identifier"].match(/^[^\.]+\.amazonaws\.com$/)
|
|
1186
|
+
bucket_prefix = if grantee["identifier"].match(/^[^\.]+\.amazonaws\.com$/)
|
|
1187
|
+
"Service"
|
|
1188
|
+
elsif grantee["identifier"] =~ /^[a-f0-9]+$/
|
|
1189
|
+
"CanonicalUser"
|
|
1190
|
+
else
|
|
1191
|
+
"AWS"
|
|
1192
|
+
end
|
|
1193
|
+
|
|
1158
1194
|
if bucket_style
|
|
1159
1195
|
statement["Principal"] << { bucket_prefix => grantee["identifier"] }
|
|
1160
1196
|
else
|