cloud-mu 1.9.0.pre.beta → 2.0.0.pre.alpha
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/Berksfile +16 -54
- data/Berksfile.lock +14 -62
- data/bin/mu-aws-setup +131 -108
- data/bin/mu-configure +311 -74
- data/bin/mu-gcp-setup +84 -62
- data/bin/mu-load-config.rb +46 -2
- data/bin/mu-self-update +11 -9
- data/bin/mu-upload-chef-artifacts +4 -4
- data/{mu.gemspec → cloud-mu.gemspec} +2 -2
- data/cookbooks/awscli/Berksfile +8 -0
- data/cookbooks/mu-activedirectory/Berksfile +11 -0
- data/cookbooks/mu-firewall/Berksfile +9 -0
- data/cookbooks/mu-firewall/metadata.rb +1 -1
- data/cookbooks/mu-glusterfs/Berksfile +10 -0
- data/cookbooks/mu-jenkins/Berksfile +14 -0
- data/cookbooks/mu-master/Berksfile +23 -0
- data/cookbooks/mu-master/attributes/default.rb +1 -1
- data/cookbooks/mu-master/metadata.rb +2 -2
- data/cookbooks/mu-master/recipes/default.rb +1 -1
- data/cookbooks/mu-master/recipes/init.rb +7 -3
- data/cookbooks/mu-master/recipes/ssl-certs.rb +1 -0
- data/cookbooks/mu-mongo/Berksfile +10 -0
- data/cookbooks/mu-openvpn/Berksfile +11 -0
- data/cookbooks/mu-php54/Berksfile +13 -0
- data/cookbooks/mu-splunk/Berksfile +10 -0
- data/cookbooks/mu-tools/Berksfile +21 -0
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +15 -15
- data/cookbooks/mu-utility/Berksfile +9 -0
- data/cookbooks/mu-utility/metadata.rb +2 -1
- data/cookbooks/nagios/Berksfile +7 -4
- data/cookbooks/s3fs/Berksfile +9 -0
- data/environments/dev.json +6 -6
- data/environments/prod.json +6 -6
- data/modules/mu.rb +20 -42
- data/modules/mu/cleanup.rb +102 -100
- data/modules/mu/cloud.rb +90 -28
- data/modules/mu/clouds/aws.rb +449 -218
- data/modules/mu/clouds/aws/alarm.rb +29 -17
- data/modules/mu/clouds/aws/cache_cluster.rb +78 -64
- data/modules/mu/clouds/aws/collection.rb +25 -18
- data/modules/mu/clouds/aws/container_cluster.rb +73 -66
- data/modules/mu/clouds/aws/database.rb +124 -116
- data/modules/mu/clouds/aws/dnszone.rb +27 -20
- data/modules/mu/clouds/aws/firewall_rule.rb +30 -22
- data/modules/mu/clouds/aws/folder.rb +18 -3
- data/modules/mu/clouds/aws/function.rb +77 -23
- data/modules/mu/clouds/aws/group.rb +19 -12
- data/modules/mu/clouds/aws/habitat.rb +153 -0
- data/modules/mu/clouds/aws/loadbalancer.rb +59 -52
- data/modules/mu/clouds/aws/log.rb +30 -23
- data/modules/mu/clouds/aws/msg_queue.rb +29 -20
- data/modules/mu/clouds/aws/notifier.rb +222 -0
- data/modules/mu/clouds/aws/role.rb +178 -90
- data/modules/mu/clouds/aws/search_domain.rb +40 -24
- data/modules/mu/clouds/aws/server.rb +169 -137
- data/modules/mu/clouds/aws/server_pool.rb +60 -83
- data/modules/mu/clouds/aws/storage_pool.rb +59 -31
- data/modules/mu/clouds/aws/user.rb +36 -27
- data/modules/mu/clouds/aws/userdata/linux.erb +101 -93
- data/modules/mu/clouds/aws/vpc.rb +250 -189
- data/modules/mu/clouds/azure.rb +132 -0
- data/modules/mu/clouds/cloudformation.rb +65 -1
- data/modules/mu/clouds/cloudformation/alarm.rb +8 -0
- data/modules/mu/clouds/cloudformation/cache_cluster.rb +7 -0
- data/modules/mu/clouds/cloudformation/collection.rb +7 -0
- data/modules/mu/clouds/cloudformation/database.rb +7 -0
- data/modules/mu/clouds/cloudformation/dnszone.rb +7 -0
- data/modules/mu/clouds/cloudformation/firewall_rule.rb +9 -2
- data/modules/mu/clouds/cloudformation/loadbalancer.rb +7 -0
- data/modules/mu/clouds/cloudformation/log.rb +7 -0
- data/modules/mu/clouds/cloudformation/server.rb +7 -0
- data/modules/mu/clouds/cloudformation/server_pool.rb +7 -0
- data/modules/mu/clouds/cloudformation/vpc.rb +7 -0
- data/modules/mu/clouds/google.rb +214 -110
- data/modules/mu/clouds/google/container_cluster.rb +42 -24
- data/modules/mu/clouds/google/database.rb +15 -6
- data/modules/mu/clouds/google/firewall_rule.rb +17 -25
- data/modules/mu/clouds/google/group.rb +13 -5
- data/modules/mu/clouds/google/habitat.rb +105 -0
- data/modules/mu/clouds/google/loadbalancer.rb +28 -20
- data/modules/mu/clouds/google/server.rb +93 -354
- data/modules/mu/clouds/google/server_pool.rb +18 -10
- data/modules/mu/clouds/google/user.rb +22 -14
- data/modules/mu/clouds/google/vpc.rb +97 -69
- data/modules/mu/config.rb +133 -38
- data/modules/mu/config/alarm.rb +25 -0
- data/modules/mu/config/cache_cluster.rb +5 -3
- data/modules/mu/config/cache_cluster.yml +23 -0
- data/modules/mu/config/database.rb +25 -16
- data/modules/mu/config/database.yml +3 -3
- data/modules/mu/config/function.rb +1 -2
- data/modules/mu/config/{project.rb → habitat.rb} +10 -10
- data/modules/mu/config/notifier.rb +85 -0
- data/modules/mu/config/notifier.yml +9 -0
- data/modules/mu/config/role.rb +1 -1
- data/modules/mu/config/search_domain.yml +2 -2
- data/modules/mu/config/server.rb +13 -1
- data/modules/mu/config/server.yml +3 -3
- data/modules/mu/config/server_pool.rb +3 -1
- data/modules/mu/config/storage_pool.rb +3 -1
- data/modules/mu/config/storage_pool.yml +19 -0
- data/modules/mu/config/vpc.rb +70 -8
- data/modules/mu/groomers/chef.rb +2 -3
- data/modules/mu/kittens.rb +500 -122
- data/modules/mu/master.rb +5 -5
- data/modules/mu/mommacat.rb +151 -91
- data/modules/tests/super_complex_bok.yml +12 -0
- data/modules/tests/super_simple_bok.yml +12 -0
- data/spec/mu/clouds/azure_spec.rb +82 -0
- data/spec/spec_helper.rb +105 -0
- metadata +26 -5
- data/modules/mu/clouds/aws/notification.rb +0 -139
- data/modules/mu/config/notification.rb +0 -44
@@ -39,7 +39,7 @@ module MU
|
|
39
39
|
@config['iam_policies'].each { |policy|
|
40
40
|
policy_name = @mu_name+"-"+policy.keys.first.upcase
|
41
41
|
MU.log "Creating IAM policy #{policy_name}"
|
42
|
-
resp = MU::Cloud::AWS.iam.create_policy(
|
42
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).create_policy(
|
43
43
|
policy_name: policy_name,
|
44
44
|
path: "/"+@deploy.deploy_id+"/",
|
45
45
|
policy_document: JSON.generate(policy.values.first),
|
@@ -50,7 +50,7 @@ module MU
|
|
50
50
|
|
51
51
|
if !@config['bare_policies']
|
52
52
|
MU.log "Creating IAM role #{@mu_name}"
|
53
|
-
resp = MU::Cloud::AWS.iam.create_role(
|
53
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).create_role(
|
54
54
|
path: "/"+@deploy.deploy_id+"/",
|
55
55
|
role_name: @mu_name,
|
56
56
|
description: "Generated by Mu",
|
@@ -62,14 +62,13 @@ module MU
|
|
62
62
|
|
63
63
|
# Called automatically by {MU::Deploy#createResources}
|
64
64
|
def groom
|
65
|
-
|
66
65
|
if @config['policies']
|
67
66
|
@config['iam_policies'] ||= []
|
68
67
|
@config['iam_policies'].concat(convert_policies_to_iam)
|
69
68
|
end
|
70
69
|
|
71
70
|
if !@config['bare_policies']
|
72
|
-
resp = MU::Cloud::AWS.iam.get_role(
|
71
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_role(
|
73
72
|
role_name: @mu_name
|
74
73
|
).role
|
75
74
|
ext_tags = resp.tags.map { |t| t.to_h }
|
@@ -78,64 +77,74 @@ module MU
|
|
78
77
|
|
79
78
|
if tag_param.size > 0
|
80
79
|
MU.log "Updating tags on IAM role #{@mu_name}", MU::NOTICE, details: tag_param
|
81
|
-
MU::Cloud::AWS.iam.tag_role(role_name: @mu_name, tags: tag_param)
|
80
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).tag_role(role_name: @mu_name, tags: tag_param)
|
82
81
|
end
|
83
82
|
end
|
84
83
|
|
85
|
-
|
84
|
+
|
85
|
+
if @config['iam_policies'] or @config['import']
|
86
86
|
attached_policies = []
|
87
|
-
configured_policies =
|
88
|
-
|
89
|
-
|
87
|
+
configured_policies = []
|
88
|
+
|
89
|
+
if @config['iam_policies']
|
90
|
+
configured_policies = @config['iam_policies'].map { |p|
|
91
|
+
@mu_name+"-"+p.keys.first.upcase
|
92
|
+
}
|
93
|
+
end
|
94
|
+
|
90
95
|
if @config['import']
|
96
|
+
MU.log "Attaching canned #{@config['import'].size > 1 ? "policies" : "policy"} #{@config['import'].join(", ")} to role #{@mu_name}", MU::NOTICE, details: @config['credentials']
|
91
97
|
configured_policies.concat(@config['import'].map { |p| p.gsub(/.*?\/([^:\/]+)$/, '\1') })
|
92
98
|
end
|
93
99
|
|
94
100
|
if !@config['bare_policies']
|
95
|
-
attached_policies = MU::Cloud::AWS.iam.list_attached_role_policies(
|
101
|
+
attached_policies = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
|
96
102
|
role_name: @mu_name
|
97
103
|
).attached_policies
|
98
104
|
attached_policies.each { |a|
|
99
105
|
if !configured_policies.include?(a.policy_name)
|
100
106
|
MU.log "Removing IAM policy #{a.policy_name} from role #{@mu_name}", MU::NOTICE
|
101
|
-
MU::Cloud::AWS::Role.purgePolicy(a.policy_arn)
|
107
|
+
MU::Cloud::AWS::Role.purgePolicy(a.policy_arn, @config['credentials'])
|
102
108
|
end
|
103
109
|
}
|
104
110
|
end
|
105
111
|
|
106
|
-
@config['iam_policies']
|
107
|
-
|
112
|
+
if @config['iam_policies']
|
113
|
+
@config['iam_policies'].each { |policy|
|
114
|
+
policy_name = @mu_name+"-"+policy.keys.first.upcase
|
108
115
|
|
109
|
-
|
110
|
-
|
111
|
-
|
116
|
+
arn = "arn:"+(MU::Cloud::AWS.isGovCloud? ? "aws-us-gov" : "aws")+":iam::"+MU::Cloud::AWS.credToAcct(@config['credentials'])+":policy/#{@deploy.deploy_id}/#{policy_name}"
|
117
|
+
resp = begin
|
118
|
+
desc = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(policy_arn: arn)
|
112
119
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
version = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy_version(
|
121
|
+
policy_arn: arn,
|
122
|
+
version_id: desc.policy.default_version_id
|
123
|
+
)
|
124
|
+
if version.policy_version.document != URI.encode(JSON.generate(policy.values.first), /[^a-z0-9\-]/i)
|
125
|
+
MU.log "Updating IAM policy #{policy_name}", MU::NOTICE, details: policy.values.first
|
126
|
+
update_policy(arn, policy.values.first)
|
127
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(policy_arn: arn)
|
128
|
+
else
|
129
|
+
desc
|
130
|
+
end
|
124
131
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
132
|
+
rescue Aws::IAM::Errors::NoSuchEntity => e
|
133
|
+
MU.log "Creating IAM policy #{policy_name}", details: policy.values.first
|
134
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_policy(
|
135
|
+
policy_name: policy_name,
|
136
|
+
path: "/"+@deploy.deploy_id+"/",
|
137
|
+
policy_document: JSON.generate(policy.values.first),
|
138
|
+
description: "Generated from inline policy document for Mu role #{@mu_name}"
|
139
|
+
)
|
140
|
+
end
|
134
141
|
|
135
|
-
|
142
|
+
}
|
143
|
+
end
|
136
144
|
end
|
137
145
|
|
138
|
-
if !@config['bare_policies'] and
|
146
|
+
if !@config['bare_policies'] and
|
147
|
+
(@config['iam_policies'] or @config['import'])
|
139
148
|
bindTo("role", @mu_name)
|
140
149
|
end
|
141
150
|
end
|
@@ -158,22 +167,22 @@ module MU
|
|
158
167
|
def cloud_desc
|
159
168
|
desc = {}
|
160
169
|
if @config['bare_policies']
|
161
|
-
desc["policies"] = MU::Cloud::AWS.iam.list_policies(
|
170
|
+
desc["policies"] = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_policies(
|
162
171
|
path_prefix: "/"+MU.deploy_id+"/"
|
163
172
|
).policies
|
164
173
|
desc["policies"].reject! { |p|
|
165
174
|
!p.policy_name.match(/^#{Regexp.quote(@mu_name)}-/)
|
166
175
|
}
|
167
176
|
else
|
168
|
-
desc["role"] = MU::Cloud::AWS.iam.get_role(
|
177
|
+
desc["role"] = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_role(
|
169
178
|
role_name: @mu_name
|
170
179
|
).role
|
171
180
|
if @config['iam_policies']
|
172
181
|
desc["policies"] = []
|
173
|
-
MU::Cloud::AWS.iam.list_attached_role_policies(
|
182
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
|
174
183
|
role_name: @mu_name
|
175
184
|
).attached_policies.each { |p|
|
176
|
-
desc["policies"] << MU::Cloud::AWS.iam.get_policy(
|
185
|
+
desc["policies"] << MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(
|
177
186
|
policy_arn: p.policy_arn
|
178
187
|
).policy
|
179
188
|
}
|
@@ -201,7 +210,7 @@ module MU
|
|
201
210
|
my_policies = cloud_desc["policies"]
|
202
211
|
my_policies.each { |p|
|
203
212
|
if p.policy_name == policy
|
204
|
-
old = MU::Cloud::AWS.iam.get_policy_version(
|
213
|
+
old = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy_version(
|
205
214
|
policy_arn: p.arn,
|
206
215
|
version_id: p.default_version_id
|
207
216
|
).policy_version
|
@@ -209,9 +218,17 @@ module MU
|
|
209
218
|
need_update = false
|
210
219
|
doc["Statement"].each { |s|
|
211
220
|
targets.each { |target|
|
212
|
-
|
213
|
-
|
214
|
-
|
221
|
+
targetstr = if target['type']
|
222
|
+
sibling = @deploy.findLitterMate(
|
223
|
+
name: target["identifier"],
|
224
|
+
type: target["type"]
|
225
|
+
)
|
226
|
+
sibling.cloudobj.arn
|
227
|
+
else
|
228
|
+
target['identifier']
|
229
|
+
end
|
230
|
+
if sibling and !s["Resource"].include?(targetstr)
|
231
|
+
s["Resource"] << targetstr
|
215
232
|
need_update = true
|
216
233
|
end
|
217
234
|
}
|
@@ -226,34 +243,34 @@ module MU
|
|
226
243
|
|
227
244
|
# Delete an IAM policy, along with attendant versions and attachments.
|
228
245
|
# @param policy_arn [String]: The ARN of the policy to purge
|
229
|
-
def self.purgePolicy(policy_arn)
|
230
|
-
attachments = MU::Cloud::AWS.iam.list_entities_for_policy(
|
246
|
+
def self.purgePolicy(policy_arn, credentials)
|
247
|
+
attachments = MU::Cloud::AWS.iam(credentials: credentials).list_entities_for_policy(
|
231
248
|
policy_arn: policy_arn
|
232
249
|
)
|
233
250
|
attachments.policy_users.each { |u|
|
234
|
-
MU::Cloud::AWS.iam.detach_user_policy(
|
251
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_user_policy(
|
235
252
|
user_name: u.user_name,
|
236
253
|
policy_arn: policy_arn
|
237
254
|
)
|
238
255
|
}
|
239
256
|
attachments.policy_groups.each { |g|
|
240
|
-
MU::Cloud::AWS.iam.detach_group_policy(
|
257
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_group_policy(
|
241
258
|
group_name: g.group_name,
|
242
259
|
policy_arn: policy_arn
|
243
260
|
)
|
244
261
|
}
|
245
262
|
attachments.policy_roles.each { |r|
|
246
|
-
MU::Cloud::AWS.iam.detach_role_policy(
|
263
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
|
247
264
|
role_name: r.role_name,
|
248
265
|
policy_arn: policy_arn
|
249
266
|
)
|
250
267
|
}
|
251
|
-
versions = MU::Cloud::AWS.iam.list_policy_versions(
|
268
|
+
versions = MU::Cloud::AWS.iam(credentials: credentials).list_policy_versions(
|
252
269
|
policy_arn: policy_arn,
|
253
270
|
).versions
|
254
271
|
versions.each { |v|
|
255
272
|
next if v.is_default_version
|
256
|
-
MU::Cloud::AWS.iam.delete_policy_version(
|
273
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_policy_version(
|
257
274
|
policy_arn: policy_arn,
|
258
275
|
version_id: v.version_id
|
259
276
|
)
|
@@ -262,51 +279,69 @@ module MU
|
|
262
279
|
# Delete the policy, unless it's one of the global canned ones owned
|
263
280
|
# by AWS
|
264
281
|
if !policy_arn.match(/^arn:aws:iam::aws:/)
|
265
|
-
MU::Cloud::AWS.iam.delete_policy(
|
282
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_policy(
|
266
283
|
policy_arn: policy_arn
|
267
284
|
)
|
268
285
|
end
|
269
286
|
end
|
270
287
|
|
288
|
+
# Does this resource type exist as a global (cloud-wide) artifact, or
|
289
|
+
# is it localized to a region/zone?
|
290
|
+
# @return [Boolean]
|
291
|
+
def self.isGlobal?
|
292
|
+
true
|
293
|
+
end
|
294
|
+
|
271
295
|
# Remove all roles associated with the currently loaded deployment.
|
272
296
|
# @param noop [Boolean]: If true, will only print what would be done
|
273
297
|
# @param ignoremaster [Boolean]: If true, will remove resources not flagged as originating from this Mu server
|
274
298
|
# @param region [String]: The cloud provider region
|
275
299
|
# @return [void]
|
276
|
-
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, flags: {})
|
300
|
+
def self.cleanup(noop: false, ignoremaster: false, region: MU.curRegion, credentials: nil, flags: {})
|
277
301
|
|
278
|
-
resp = MU::Cloud::AWS.iam.list_policies(
|
302
|
+
resp = MU::Cloud::AWS.iam(credentials: credentials).list_policies(
|
279
303
|
path_prefix: "/"+MU.deploy_id+"/"
|
280
304
|
)
|
281
305
|
if resp and resp.policies
|
282
306
|
resp.policies.each { |policy|
|
283
307
|
MU.log "Deleting IAM policy /#{MU.deploy_id}/#{policy.policy_name}"
|
284
308
|
if !noop
|
285
|
-
purgePolicy(policy.arn)
|
309
|
+
purgePolicy(policy.arn, credentials)
|
286
310
|
end
|
287
311
|
}
|
288
312
|
end
|
289
313
|
|
290
|
-
resp = MU::Cloud::AWS.iam.list_roles(
|
314
|
+
resp = MU::Cloud::AWS.iam(credentials: credentials).list_roles(
|
291
315
|
path_prefix: "/"+MU.deploy_id+"/"
|
292
316
|
)
|
293
317
|
if resp and resp.roles
|
294
318
|
resp.roles.each { |r|
|
295
319
|
MU.log "Deleting IAM role #{r.role_name}"
|
296
320
|
if !noop
|
321
|
+
# purgePolicy won't touch roles we don't own, so gently detach
|
322
|
+
# those first
|
323
|
+
detachables = MU::Cloud::AWS.iam(credentials: credentials).list_attached_role_policies(
|
324
|
+
role_name: r.role_name
|
325
|
+
).attached_policies
|
326
|
+
detachables.each { |rp|
|
327
|
+
MU::Cloud::AWS.iam(credentials: credentials).detach_role_policy(
|
328
|
+
role_name: r.role_name,
|
329
|
+
policy_arn: rp.policy_arn
|
330
|
+
)
|
331
|
+
}
|
297
332
|
|
298
333
|
begin
|
299
|
-
MU::Cloud::AWS.iam.remove_role_from_instance_profile(
|
334
|
+
MU::Cloud::AWS.iam(credentials: credentials).remove_role_from_instance_profile(
|
300
335
|
instance_profile_name: r.role_name,
|
301
336
|
role_name: r.role_name
|
302
337
|
)
|
303
|
-
MU::Cloud::AWS.iam.delete_instance_profile(instance_profile_name: r.role_name)
|
338
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_instance_profile(instance_profile_name: r.role_name)
|
304
339
|
rescue Aws::IAM::Errors::ValidationError => e
|
305
340
|
MU.log "Cleaning up IAM role #{r.role_name}: #{e.inspect}", MU::WARN
|
306
341
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
307
342
|
end
|
308
343
|
|
309
|
-
MU::Cloud::AWS.iam.delete_role(
|
344
|
+
MU::Cloud::AWS.iam(credentials: credentials).delete_role(
|
310
345
|
role_name: r.role_name
|
311
346
|
)
|
312
347
|
end
|
@@ -320,7 +355,7 @@ module MU
|
|
320
355
|
# @param region [String]: The cloud provider region.
|
321
356
|
# @param flags [Hash]: Optional flags
|
322
357
|
# @return [OpenStruct]: The cloud provider's complete descriptions of matching user group.
|
323
|
-
def self.find(cloud_id: nil, region: MU.curRegion, flags: {})
|
358
|
+
def self.find(cloud_id: nil, region: MU.curRegion, credentials: nil, flags: {})
|
324
359
|
found = nil
|
325
360
|
|
326
361
|
found
|
@@ -331,13 +366,22 @@ module MU
|
|
331
366
|
def bindTo(entitytype, entityname)
|
332
367
|
if entitytype == "instance_profile"
|
333
368
|
begin
|
334
|
-
MU::Cloud::AWS.iam.
|
335
|
-
instance_profile_name: entityname
|
336
|
-
|
337
|
-
|
369
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
|
370
|
+
instance_profile_name: entityname
|
371
|
+
).instance_profile
|
372
|
+
|
373
|
+
if !resp.roles.map { |r| r.role_name}.include?(@mu_name)
|
374
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).add_role_to_instance_profile(
|
375
|
+
instance_profile_name: entityname,
|
376
|
+
role_name: @mu_name
|
377
|
+
)
|
378
|
+
end
|
379
|
+
rescue Exception => e
|
380
|
+
MU.log "Error binding role #{@mu_name} to instance profile #{entityname}: #{e.message}", MU::ERR
|
381
|
+
raise e
|
338
382
|
end
|
339
383
|
elsif ["user", "group", "role"].include?(entitytype)
|
340
|
-
mypolicies = MU::Cloud::AWS.iam.list_policies(
|
384
|
+
mypolicies = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_policies(
|
341
385
|
path_prefix: "/"+@deploy.deploy_id+"/"
|
342
386
|
).policies
|
343
387
|
mypolicies.reject! { |p|
|
@@ -347,47 +391,57 @@ module MU
|
|
347
391
|
if @config['import']
|
348
392
|
@config['import'].each { |policy|
|
349
393
|
if !policy.match(/^arn:/i)
|
350
|
-
|
394
|
+
p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/"+policy
|
395
|
+
end
|
396
|
+
retried = false
|
397
|
+
begin
|
398
|
+
mypolicies << MU::Cloud::AWS.iam(credentials: @config['credentials']).get_policy(
|
399
|
+
policy_arn: p_arn
|
400
|
+
).policy
|
401
|
+
rescue Aws::IAM::Errors::NoSuchEntity => e
|
402
|
+
if !retried
|
403
|
+
p_arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(@config["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/service-role/"+policy
|
404
|
+
retried = true
|
405
|
+
retry
|
406
|
+
end
|
407
|
+
raise e
|
351
408
|
end
|
352
|
-
mypolicies << MU::Cloud::AWS.iam.get_policy(
|
353
|
-
policy_arn: policy
|
354
|
-
).policy
|
355
409
|
}
|
356
410
|
end
|
357
411
|
|
358
412
|
mypolicies.each { |p|
|
359
413
|
if entitytype == "user"
|
360
|
-
resp = MU::Cloud::AWS.iam.list_attached_user_policies(
|
414
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_user_policies(
|
361
415
|
path_prefix: "/"+@deploy.deploy_id+"/",
|
362
416
|
user_name: entityname
|
363
417
|
)
|
364
418
|
if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
|
365
419
|
MU.log "Attaching IAM policy #{p.policy_name} to user #{entityname}", MU::NOTICE
|
366
|
-
MU::Cloud::AWS.iam.attach_user_policy(
|
420
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_user_policy(
|
367
421
|
policy_arn: p.arn,
|
368
422
|
user_name: entityname
|
369
423
|
)
|
370
424
|
end
|
371
425
|
elsif entitytype == "group"
|
372
|
-
resp = MU::Cloud::AWS.iam.list_attached_group_policies(
|
426
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_group_policies(
|
373
427
|
path_prefix: "/"+@deploy.deploy_id+"/",
|
374
428
|
group_name: entityname
|
375
429
|
)
|
376
430
|
if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
|
377
431
|
MU.log "Attaching policy #{p.policy_name} to group #{entityname}", MU::NOTICE
|
378
|
-
MU::Cloud::AWS.iam.attach_group_policy(
|
432
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_group_policy(
|
379
433
|
policy_arn: p.arn,
|
380
434
|
group_name: entityname
|
381
435
|
)
|
382
436
|
end
|
383
437
|
elsif entitytype == "role"
|
384
|
-
resp = MU::Cloud::AWS.iam.list_attached_role_policies(
|
438
|
+
resp = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_attached_role_policies(
|
385
439
|
role_name: entityname
|
386
440
|
)
|
387
441
|
|
388
442
|
if !resp or !resp.attached_policies.map { |p| p.policy_name }.include?(p.policy_name)
|
389
443
|
MU.log "Attaching policy #{p.policy_name} to role #{entityname}", MU::NOTICE
|
390
|
-
MU::Cloud::AWS.iam.attach_role_policy(
|
444
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).attach_role_policy(
|
391
445
|
policy_arn: p.arn,
|
392
446
|
role_name: entityname
|
393
447
|
)
|
@@ -407,18 +461,19 @@ module MU
|
|
407
461
|
end
|
408
462
|
|
409
463
|
resp = begin
|
410
|
-
MU
|
464
|
+
MU.log "Creating instance profile #{@mu_name} #{@config['credentials']}"
|
465
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_instance_profile(
|
411
466
|
instance_profile_name: @mu_name
|
412
467
|
)
|
413
468
|
rescue Aws::IAM::Errors::EntityAlreadyExists => e
|
414
|
-
MU::Cloud::AWS.iam.get_instance_profile(
|
469
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(
|
415
470
|
instance_profile_name: @mu_name
|
416
471
|
)
|
417
472
|
end
|
418
473
|
|
419
474
|
# make sure it's really there before moving on
|
420
475
|
begin
|
421
|
-
MU::Cloud::AWS.iam.get_instance_profile(instance_profile_name: @mu_name)
|
476
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).get_instance_profile(instance_profile_name: @mu_name)
|
422
477
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
423
478
|
MU.log e.inspect, MU::WARN
|
424
479
|
sleep 10
|
@@ -469,6 +524,12 @@ module MU
|
|
469
524
|
"description" => "Type of entity which will be permitted to assume this role. See +entity_id+ for details.",
|
470
525
|
"enum" => ["service", "aws", "federated"]+aws_resource_types
|
471
526
|
},
|
527
|
+
"assume_method" => {
|
528
|
+
"type" => "string",
|
529
|
+
"description" => "https://docs.aws.amazon.com/STS/latest/APIReference/API_Operations.html",
|
530
|
+
"enum" => ["basic", "saml", "web"],
|
531
|
+
"default" => "basic"
|
532
|
+
},
|
472
533
|
"entity_id" => {
|
473
534
|
"type" => "string",
|
474
535
|
"description" => "An identifier appropriate for the +entity_type+ which is allowed to assume this role- see details for valid formats.\n
|
@@ -501,15 +562,24 @@ module MU
|
|
501
562
|
|
502
563
|
if role['import']
|
503
564
|
role['import'].each { |policy|
|
504
|
-
if !policy.match(/^arn:/i)
|
505
|
-
|
565
|
+
arn = if !policy.match(/^arn:/i)
|
566
|
+
"arn:"+(MU::Cloud::AWS.isGovCloud?(role["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/"+policy
|
567
|
+
else
|
568
|
+
policy
|
506
569
|
end
|
570
|
+
retried = false
|
507
571
|
begin
|
508
|
-
MU::Cloud::AWS.iam.get_policy(policy_arn:
|
572
|
+
MU::Cloud::AWS.iam(credentials: role['credentials']).get_policy(policy_arn: arn)
|
509
573
|
rescue Aws::IAM::Errors::NoSuchEntity => e
|
510
|
-
|
574
|
+
if !retried
|
575
|
+
arn = "arn:"+(MU::Cloud::AWS.isGovCloud?(role["region"]) ? "aws-us-gov" : "aws")+":iam::aws:policy/service-role/"+policy
|
576
|
+
retried = true
|
577
|
+
retry
|
578
|
+
end
|
579
|
+
MU.log "No such canned AWS IAM policy '#{arn}'", MU::ERR
|
511
580
|
ok = false
|
512
581
|
end
|
582
|
+
policy = arn
|
513
583
|
}
|
514
584
|
end
|
515
585
|
|
@@ -524,6 +594,19 @@ module MU
|
|
524
594
|
ok = false
|
525
595
|
end
|
526
596
|
|
597
|
+
if role['policies']
|
598
|
+
role['policies'].each { |policy|
|
599
|
+
policy['targets'].each { |target|
|
600
|
+
if target['type']
|
601
|
+
role['dependencies'] ||= []
|
602
|
+
role['dependencies'] << {
|
603
|
+
"name" => target['identifier'],
|
604
|
+
"type" => target['type']
|
605
|
+
}
|
606
|
+
end
|
607
|
+
}
|
608
|
+
}
|
609
|
+
end
|
527
610
|
|
528
611
|
ok
|
529
612
|
end
|
@@ -540,7 +623,7 @@ module MU
|
|
540
623
|
"Version" => "2012-10-17",
|
541
624
|
"Statement" => [
|
542
625
|
{
|
543
|
-
"Sid" => policy["name"],
|
626
|
+
"Sid" => policy["name"].gsub(/[^0-9A-Za-z]*/, ""),
|
544
627
|
"Effect" => policy['flag'].capitalize,
|
545
628
|
"Action" => [],
|
546
629
|
"Resource" => []
|
@@ -598,13 +681,18 @@ module MU
|
|
598
681
|
role_policy_doc = {
|
599
682
|
"Version" => "2012-10-17",
|
600
683
|
}
|
601
|
-
|
684
|
+
|
602
685
|
statements = []
|
603
686
|
if @config['can_assume']
|
687
|
+
act_map = {
|
688
|
+
"basic" => "sts:AssumeRole",
|
689
|
+
"saml" => "sts:AssumeRoleWithSAML",
|
690
|
+
"web" => "sts:AssumeRoleWithWebIdentity"
|
691
|
+
}
|
604
692
|
@config['can_assume'].each { |svc|
|
605
693
|
statement = {
|
606
694
|
"Effect" => "Allow",
|
607
|
-
"Action" =>
|
695
|
+
"Action" => act_map[svc['assume_method']],
|
608
696
|
"Principal" => {}
|
609
697
|
}
|
610
698
|
if ["service", "iam", "federated"].include?(svc["entity_type"])
|
@@ -632,17 +720,17 @@ module MU
|
|
632
720
|
# Update a policy, handling deletion of old versions as needed
|
633
721
|
def update_policy(arn, doc)
|
634
722
|
begin
|
635
|
-
MU::Cloud::AWS.iam.create_policy_version(
|
723
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).create_policy_version(
|
636
724
|
policy_arn: arn,
|
637
725
|
set_as_default: true,
|
638
726
|
policy_document: JSON.generate(doc)
|
639
727
|
)
|
640
728
|
rescue Aws::IAM::Errors::LimitExceeded => e
|
641
|
-
delete_version = MU::Cloud::AWS.iam.list_policy_versions(
|
729
|
+
delete_version = MU::Cloud::AWS.iam(credentials: @config['credentials']).list_policy_versions(
|
642
730
|
policy_arn: arn,
|
643
731
|
).versions.last.version_id
|
644
732
|
MU.log "Purging oldest version (#{delete_version}) of IAM policy #{arn}", MU::NOTICE
|
645
|
-
MU::Cloud::AWS.iam.delete_policy_version(
|
733
|
+
MU::Cloud::AWS.iam(credentials: @config['credentials']).delete_policy_version(
|
646
734
|
policy_arn: arn,
|
647
735
|
version_id: delete_version
|
648
736
|
)
|