miam 0.1.0 → 0.1.1

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.
@@ -1,6 +1,6 @@
1
1
  class Miam::DSL::Context::User
2
2
  def initialize(name, &block)
3
- @name = name
3
+ @user_name = name
4
4
  @result = {:groups => [], :policies => {}}
5
5
  instance_eval(&block)
6
6
  end
@@ -21,13 +21,13 @@ class Miam::DSL::Context::User
21
21
  name = name.to_s
22
22
 
23
23
  if @result[:policies][name]
24
- raise "User `#{name}` > Policy `#{name}`: already defined"
24
+ raise "User `#{@user_name}` > Policy `#{name}`: already defined"
25
25
  end
26
26
 
27
27
  policy_document = yield
28
28
 
29
29
  unless policy_document.kind_of?(Hash)
30
- raise "User `#{name}` > Policy `#{name}`: wrong argument type #{policy_document.class} (expected Hash)"
30
+ raise "User `#{@user_name}` > Policy `#{name}`: wrong argument type #{policy_document.class} (expected Hash)"
31
31
  end
32
32
 
33
33
  @result[:policies][name] = policy_document
@@ -12,6 +12,8 @@ class Miam::DSL::Converter
12
12
  [
13
13
  output_users(@exported[:users]),
14
14
  output_groups(@exported[:groups]),
15
+ output_roles(@exported[:roles]),
16
+ output_instance_profiles(@exported[:instance_profiles]),
15
17
  ].join("\n")
16
18
  end
17
19
 
@@ -72,6 +74,62 @@ end
72
74
  EOS
73
75
  end
74
76
 
77
+ def output_roles(roles)
78
+ roles.each.sort_by {|k, v| k }.map {|role_name, attrs|
79
+ output_role(role_name, attrs)
80
+ }.join("\n")
81
+ end
82
+
83
+ def output_role(role_name, attrs)
84
+ role_options = {:path => attrs[:path]}
85
+
86
+ <<-EOS
87
+ role #{role_name.inspect}, #{Miam::Utils.unbrace(role_options.inspect)} do
88
+ #{output_role_instance_profiles(attrs[:instance_profiles])}
89
+
90
+ #{output_assume_role_policy_document(attrs[:assume_role_policy_document])}
91
+
92
+ #{output_policies(attrs[:policies])}
93
+ end
94
+ EOS
95
+ end
96
+
97
+ def output_role_instance_profiles(instance_profiles)
98
+ if instance_profiles.empty?
99
+ instance_profiles = ['# no instance_profile']
100
+ else
101
+ instance_profiles = instance_profiles.map {|i| i.inspect }
102
+ end
103
+
104
+ instance_profiles = "\n " + instance_profiles.join(",\n ") + "\n "
105
+ "instance_profiles(#{instance_profiles})"
106
+ end
107
+
108
+ def output_instance_profiles(instance_profiles)
109
+ instance_profiles.each.sort_by {|k, v| k }.map {|instance_profile_name, attrs|
110
+ output_instance_profile(instance_profile_name, attrs)
111
+ }.join("\n")
112
+ end
113
+
114
+ def output_assume_role_policy_document(assume_role_policy_document)
115
+ assume_role_policy_document = assume_role_policy_document.pretty_inspect
116
+ assume_role_policy_document.gsub!("\n", "\n ").strip!
117
+
118
+ <<-EOS.strip
119
+ assume_role_policy_document do
120
+ #{assume_role_policy_document}
121
+ end
122
+ EOS
123
+ end
124
+
125
+ def output_instance_profile(instance_profile_name, attrs)
126
+ instance_profile_options = {:path => attrs[:path]}
127
+
128
+ <<-EOS
129
+ instance_profile #{instance_profile_name.inspect}, #{Miam::Utils.unbrace(instance_profile_options.inspect)}
130
+ EOS
131
+ end
132
+
75
133
  def output_policies(policies)
76
134
  policies.map {|policy_name, policy_document|
77
135
  output_policy(policy_name, policy_document)
data/lib/miam/exporter.rb CHANGED
@@ -11,19 +11,24 @@ class Miam::Exporter
11
11
  def export(&block)
12
12
  users = list_users
13
13
  groups = list_groups
14
+ roles = list_roles
15
+ instance_profiles = list_instance_profiles
14
16
  group_users = {}
17
+ instance_profile_roles = {}
15
18
 
16
19
  export_options = {
17
- :progress_total => (users.length + groups.length),
20
+ :progress_total => (users.length + groups.length + roles.length + instance_profiles.length),
18
21
  :progress => 0,
19
22
  }
20
23
 
21
24
  expected = {
22
25
  :users => export_users(users, group_users, export_options, &block),
23
26
  :groups => export_groups(groups, export_options, &block),
27
+ :roles => export_roles(roles, instance_profile_roles, export_options, &block),
28
+ :instance_profiles => export_instance_profiles(instance_profiles, export_options, &block),
24
29
  }
25
30
 
26
- [expected, group_users]
31
+ [expected, group_users, instance_profile_roles]
27
32
  end
28
33
 
29
34
  private
@@ -123,6 +128,82 @@ class Miam::Exporter
123
128
  result
124
129
  end
125
130
 
131
+ def export_roles(roles, instance_profile_roles, export_options = {})
132
+ result = {}
133
+
134
+ roles.each do |role|
135
+ role_name = role.role_name
136
+
137
+ instance_profiles = export_role_instance_profiles(role_name)
138
+
139
+ instance_profiles.each do |instance_profile_name|
140
+ instance_profile_roles[instance_profile_name] ||= []
141
+ instance_profile_roles[instance_profile_name] << role_name
142
+ end
143
+
144
+ document = CGI.unescape(role.assume_role_policy_document)
145
+
146
+ result[role_name] = {
147
+ :path => role.path,
148
+ :assume_role_policy_document => JSON.parse(document),
149
+ :instance_profiles => instance_profiles,
150
+ :policies => export_role_policies(role_name),
151
+ }
152
+
153
+ export_options[:progress] += 1
154
+ yield(export_options) if block_given?
155
+ end
156
+
157
+ result
158
+ end
159
+
160
+ def export_role_instance_profiles(role_name)
161
+ @iam.list_instance_profiles_for_role(:role_name => role_name).map {|resp|
162
+ resp.instance_profiles.map do |instance_profile|
163
+ instance_profile.instance_profile_name
164
+ end
165
+ }.flatten
166
+ end
167
+
168
+ def export_role_policies(role_name)
169
+ result = {}
170
+
171
+ @iam.list_role_policies(:role_name => role_name).each do |resp|
172
+ resp.policy_names.map do |policy_name|
173
+ policy = @iam.get_role_policy(:role_name => role_name, :policy_name => policy_name)
174
+ document = CGI.unescape(policy.policy_document)
175
+ result[policy_name] = JSON.parse(document)
176
+ end
177
+ end
178
+
179
+ result
180
+ end
181
+
182
+ def export_instance_profiles(instance_profiles, export_options = {})
183
+ result = {}
184
+
185
+ instance_profiles.each do |instance_profile|
186
+ instance_profile_name = instance_profile.instance_profile_name
187
+
188
+ result[instance_profile_name] = {
189
+ :path => instance_profile.path,
190
+ }
191
+
192
+ export_options[:progress] += 1
193
+ yield(export_options) if block_given?
194
+ end
195
+
196
+ result
197
+ end
198
+
199
+ def export_role_instance_profiles(role_name)
200
+ @iam.list_instance_profiles_for_role(:role_name => role_name).map {|resp|
201
+ resp.instance_profiles.map do |instance_profile|
202
+ instance_profile.instance_profile_name
203
+ end
204
+ }.flatten
205
+ end
206
+
126
207
  def list_users
127
208
  @iam.list_users.map {|resp|
128
209
  resp.users.to_a
@@ -134,4 +215,16 @@ class Miam::Exporter
134
215
  resp.groups.to_a
135
216
  }.flatten
136
217
  end
218
+
219
+ def list_roles
220
+ @iam.list_roles.map {|resp|
221
+ resp.roles.to_a
222
+ }.flatten
223
+ end
224
+
225
+ def list_instance_profiles
226
+ @iam.list_instance_profiles.map {|resp|
227
+ resp.instance_profiles.to_a
228
+ }.flatten
229
+ end
137
230
  end
data/lib/miam/logger.rb CHANGED
@@ -16,12 +16,11 @@ class Miam::Logger < ::Logger
16
16
  end
17
17
 
18
18
  module Helper
19
- def log(level, message, options = {})
20
- options = (@options || {}).merge(options)
19
+ def log(level, message, log_options = {})
21
20
  message = "[#{level.to_s.upcase}] #{message}" unless level == :info
22
- message << ' (dry-run)' if options[:dry_run]
23
- message = message.send(options[:color]) if options[:color]
24
- logger = options[:logger] || Miam::Logger.instance
21
+ message << ' (dry-run)' if @options[:dry_run]
22
+ message = message.send(log_options[:color]) if log_options[:color]
23
+ logger = @options[:logger] || Miam::Logger.instance
25
24
  logger.send(level, message)
26
25
  end
27
26
  end
@@ -1,4 +1,6 @@
1
1
  class Miam::PasswordManager
2
+ include Miam::Logger::Helper
3
+
2
4
  def initialize(output, options = {})
3
5
  @output = output
4
6
  @options = options
@@ -11,6 +13,8 @@ class Miam::PasswordManager
11
13
  end
12
14
 
13
15
  def puts_password(user, type, password)
16
+ log(:info, "User `#{user}` > `#{type}`: put password to `#{@output}`")
17
+
14
18
  open_output do |f|
15
19
  f.puts("#{user},#{type},#{password}")
16
20
  end
data/lib/miam/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Miam
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -5,7 +5,7 @@ describe 'create' do
5
5
  it do
6
6
  updated = apply(subject) { '' }
7
7
  expect(updated).to be_falsey
8
- expect(export).to eq({:users=>{}, :groups=>{}})
8
+ expect(export).to eq({:users=>{}, :groups=>{}, :roles=>{}, :instance_profiles=>{}})
9
9
  end
10
10
  end
11
11
 
@@ -53,6 +53,32 @@ describe 'create' do
53
53
  [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
54
54
  end
55
55
  end
56
+
57
+ role "my-role", :path=>"/any/" do
58
+ instance_profiles(
59
+ "my-instance-profile"
60
+ )
61
+
62
+ assume_role_policy_document do
63
+ {"Version"=>"2012-10-17",
64
+ "Statement"=>
65
+ [{"Sid"=>"",
66
+ "Effect"=>"Allow",
67
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
68
+ "Action"=>"sts:AssumeRole"}]}
69
+ end
70
+
71
+ policy "role-policy" do
72
+ {"Statement"=>
73
+ [{"Action"=>
74
+ ["s3:Get*",
75
+ "s3:List*"],
76
+ "Effect"=>"Allow",
77
+ "Resource"=>"*"}]}
78
+ end
79
+ end
80
+
81
+ instance_profile "my-instance-profile", :path=>"/profile/"
56
82
  RUBY
57
83
  end
58
84
 
@@ -96,7 +122,25 @@ describe 'create' do
96
122
  {"Statement"=>
97
123
  [{"Effect"=>"Allow",
98
124
  "Action"=>"ses:SendRawEmail",
99
- "Resource"=>"*"}]}}}}}
125
+ "Resource"=>"*"}]}}}},
126
+ :roles=>
127
+ {"my-role"=>
128
+ {:path=>"/any/",
129
+ :assume_role_policy_document=>
130
+ {"Version"=>"2012-10-17",
131
+ "Statement"=>
132
+ [{"Sid"=>"",
133
+ "Effect"=>"Allow",
134
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
135
+ "Action"=>"sts:AssumeRole"}]},
136
+ :instance_profiles=>["my-instance-profile"],
137
+ :policies=>
138
+ {"role-policy"=>
139
+ {"Statement"=>
140
+ [{"Action"=>["s3:Get*", "s3:List*"],
141
+ "Effect"=>"Allow",
142
+ "Resource"=>"*"}]}}}},
143
+ :instance_profiles=>{"my-instance-profile"=>{:path=>"/profile/"}}}
100
144
  )
101
145
  end
102
146
  end
@@ -107,7 +151,7 @@ describe 'create' do
107
151
  it do
108
152
  updated = apply(subject) { dsl }
109
153
  expect(updated).to be_falsey
110
- expect(export).to eq({:users=>{}, :groups=>{}})
154
+ expect(export).to eq({:users=>{}, :groups=>{}, :roles=>{}, :instance_profiles=>{}})
111
155
  end
112
156
  end
113
157
  end
@@ -42,6 +42,32 @@ describe 'delete' do
42
42
  [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
43
43
  end
44
44
  end
45
+
46
+ role "my-role", :path=>"/any/" do
47
+ instance_profiles(
48
+ "my-instance-profile"
49
+ )
50
+
51
+ assume_role_policy_document do
52
+ {"Version"=>"2012-10-17",
53
+ "Statement"=>
54
+ [{"Sid"=>"",
55
+ "Effect"=>"Allow",
56
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
57
+ "Action"=>"sts:AssumeRole"}]}
58
+ end
59
+
60
+ policy "role-policy" do
61
+ {"Statement"=>
62
+ [{"Action"=>
63
+ ["s3:Get*",
64
+ "s3:List*"],
65
+ "Effect"=>"Allow",
66
+ "Resource"=>"*"}]}
67
+ end
68
+ end
69
+
70
+ instance_profile "my-instance-profile", :path=>"/profile/"
45
71
  RUBY
46
72
  end
47
73
 
@@ -79,7 +105,25 @@ describe 'delete' do
79
105
  {"Statement"=>
80
106
  [{"Effect"=>"Allow",
81
107
  "Action"=>"ses:SendRawEmail",
82
- "Resource"=>"*"}]}}}}}
108
+ "Resource"=>"*"}]}}}},
109
+ :roles=>
110
+ {"my-role"=>
111
+ {:path=>"/any/",
112
+ :assume_role_policy_document=>
113
+ {"Version"=>"2012-10-17",
114
+ "Statement"=>
115
+ [{"Sid"=>"",
116
+ "Effect"=>"Allow",
117
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
118
+ "Action"=>"sts:AssumeRole"}]},
119
+ :instance_profiles=>["my-instance-profile"],
120
+ :policies=>
121
+ {"role-policy"=>
122
+ {"Statement"=>
123
+ [{"Action"=>["s3:Get*", "s3:List*"],
124
+ "Effect"=>"Allow",
125
+ "Resource"=>"*"}]}}}},
126
+ :instance_profiles=>{"my-instance-profile"=>{:path=>"/profile/"}}}
83
127
  end
84
128
 
85
129
  before(:each) do
@@ -122,6 +166,32 @@ describe 'delete' do
122
166
  {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
123
167
  end
124
168
  end
169
+
170
+ role "my-role", :path=>"/any/" do
171
+ instance_profiles(
172
+ "my-instance-profile"
173
+ )
174
+
175
+ assume_role_policy_document do
176
+ {"Version"=>"2012-10-17",
177
+ "Statement"=>
178
+ [{"Sid"=>"",
179
+ "Effect"=>"Allow",
180
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
181
+ "Action"=>"sts:AssumeRole"}]}
182
+ end
183
+
184
+ policy "role-policy" do
185
+ {"Statement"=>
186
+ [{"Action"=>
187
+ ["s3:Get*",
188
+ "s3:List*"],
189
+ "Effect"=>"Allow",
190
+ "Resource"=>"*"}]}
191
+ end
192
+ end
193
+
194
+ instance_profile "my-instance-profile", :path=>"/profile/"
125
195
  RUBY
126
196
  end
127
197
 
@@ -162,6 +232,32 @@ describe 'delete' do
162
232
  [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
163
233
  end
164
234
  end
235
+
236
+ role "my-role", :path=>"/any/" do
237
+ instance_profiles(
238
+ "my-instance-profile"
239
+ )
240
+
241
+ assume_role_policy_document do
242
+ {"Version"=>"2012-10-17",
243
+ "Statement"=>
244
+ [{"Sid"=>"",
245
+ "Effect"=>"Allow",
246
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
247
+ "Action"=>"sts:AssumeRole"}]}
248
+ end
249
+
250
+ policy "role-policy" do
251
+ {"Statement"=>
252
+ [{"Action"=>
253
+ ["s3:Get*",
254
+ "s3:List*"],
255
+ "Effect"=>"Allow",
256
+ "Resource"=>"*"}]}
257
+ end
258
+ end
259
+
260
+ instance_profile "my-instance-profile", :path=>"/profile/"
165
261
  RUBY
166
262
  end
167
263
 
@@ -194,6 +290,32 @@ describe 'delete' do
194
290
  {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
195
291
  end
196
292
  end
293
+
294
+ role "my-role", :path=>"/any/" do
295
+ instance_profiles(
296
+ "my-instance-profile"
297
+ )
298
+
299
+ assume_role_policy_document do
300
+ {"Version"=>"2012-10-17",
301
+ "Statement"=>
302
+ [{"Sid"=>"",
303
+ "Effect"=>"Allow",
304
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
305
+ "Action"=>"sts:AssumeRole"}]}
306
+ end
307
+
308
+ policy "role-policy" do
309
+ {"Statement"=>
310
+ [{"Action"=>
311
+ ["s3:Get*",
312
+ "s3:List*"],
313
+ "Effect"=>"Allow",
314
+ "Resource"=>"*"}]}
315
+ end
316
+ end
317
+
318
+ instance_profile "my-instance-profile", :path=>"/profile/"
197
319
  RUBY
198
320
  end
199
321
 
@@ -219,4 +341,202 @@ describe 'delete' do
219
341
  end
220
342
  end
221
343
  end
344
+
345
+ context 'when delete instance_profile' do
346
+ let(:delete_instance_profiles_dsl) do
347
+ <<-RUBY
348
+ user "bob", :path=>"/devloper/" do
349
+ login_profile :password_reset_required=>true
350
+
351
+ groups(
352
+ "Admin",
353
+ "SES"
354
+ )
355
+
356
+ policy "S3" do
357
+ {"Statement"=>
358
+ [{"Action"=>
359
+ ["s3:Get*",
360
+ "s3:List*"],
361
+ "Effect"=>"Allow",
362
+ "Resource"=>"*"}]}
363
+ end
364
+ end
365
+
366
+ user "mary", :path=>"/staff/" do
367
+ policy "S3" do
368
+ {"Statement"=>
369
+ [{"Action"=>
370
+ ["s3:Get*",
371
+ "s3:List*"],
372
+ "Effect"=>"Allow",
373
+ "Resource"=>"*"}]}
374
+ end
375
+ end
376
+
377
+ group "Admin", :path=>"/admin/" do
378
+ policy "Admin" do
379
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
380
+ end
381
+ end
382
+
383
+ group "SES", :path=>"/ses/" do
384
+ policy "ses-policy" do
385
+ {"Statement"=>
386
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
387
+ end
388
+ end
389
+
390
+ role "my-role", :path=>"/any/" do
391
+ instance_profiles(
392
+ )
393
+
394
+ assume_role_policy_document do
395
+ {"Version"=>"2012-10-17",
396
+ "Statement"=>
397
+ [{"Sid"=>"",
398
+ "Effect"=>"Allow",
399
+ "Principal"=>{"Service"=>"ec2.amazonaws.com"},
400
+ "Action"=>"sts:AssumeRole"}]}
401
+ end
402
+
403
+ policy "role-policy" do
404
+ {"Statement"=>
405
+ [{"Action"=>
406
+ ["s3:Get*",
407
+ "s3:List*"],
408
+ "Effect"=>"Allow",
409
+ "Resource"=>"*"}]}
410
+ end
411
+ end
412
+ RUBY
413
+ end
414
+
415
+ subject { client }
416
+
417
+ it do
418
+ updated = apply(subject) { delete_instance_profiles_dsl }
419
+ expect(updated).to be_truthy
420
+ expected[:roles]["my-role"][:instance_profiles] = []
421
+ expected[:instance_profiles].delete("my-instance-profile")
422
+ expect(export).to eq expected
423
+ end
424
+ end
425
+
426
+ context 'when delete role' do
427
+ let(:delete_role_dsl) do
428
+ <<-RUBY
429
+ user "bob", :path=>"/devloper/" do
430
+ login_profile :password_reset_required=>true
431
+
432
+ groups(
433
+ "Admin",
434
+ "SES"
435
+ )
436
+
437
+ policy "S3" do
438
+ {"Statement"=>
439
+ [{"Action"=>
440
+ ["s3:Get*",
441
+ "s3:List*"],
442
+ "Effect"=>"Allow",
443
+ "Resource"=>"*"}]}
444
+ end
445
+ end
446
+
447
+ user "mary", :path=>"/staff/" do
448
+ policy "S3" do
449
+ {"Statement"=>
450
+ [{"Action"=>
451
+ ["s3:Get*",
452
+ "s3:List*"],
453
+ "Effect"=>"Allow",
454
+ "Resource"=>"*"}]}
455
+ end
456
+ end
457
+
458
+ group "Admin", :path=>"/admin/" do
459
+ policy "Admin" do
460
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
461
+ end
462
+ end
463
+
464
+ group "SES", :path=>"/ses/" do
465
+ policy "ses-policy" do
466
+ {"Statement"=>
467
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
468
+ end
469
+ end
470
+
471
+ instance_profile "my-instance-profile", :path=>"/profile/"
472
+ RUBY
473
+ end
474
+
475
+ subject { client }
476
+
477
+ it do
478
+ updated = apply(subject) { delete_role_dsl }
479
+ expect(updated).to be_truthy
480
+ expected[:roles].delete("my-role")
481
+ expect(export).to eq expected
482
+ end
483
+ end
484
+
485
+ context 'when delete role and instance_profile' do
486
+ let(:delete_role_and_instance_profile_dsl) do
487
+ <<-RUBY
488
+ user "bob", :path=>"/devloper/" do
489
+ login_profile :password_reset_required=>true
490
+
491
+ groups(
492
+ "Admin",
493
+ "SES"
494
+ )
495
+
496
+ policy "S3" do
497
+ {"Statement"=>
498
+ [{"Action"=>
499
+ ["s3:Get*",
500
+ "s3:List*"],
501
+ "Effect"=>"Allow",
502
+ "Resource"=>"*"}]}
503
+ end
504
+ end
505
+
506
+ user "mary", :path=>"/staff/" do
507
+ policy "S3" do
508
+ {"Statement"=>
509
+ [{"Action"=>
510
+ ["s3:Get*",
511
+ "s3:List*"],
512
+ "Effect"=>"Allow",
513
+ "Resource"=>"*"}]}
514
+ end
515
+ end
516
+
517
+ group "Admin", :path=>"/admin/" do
518
+ policy "Admin" do
519
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
520
+ end
521
+ end
522
+
523
+ group "SES", :path=>"/ses/" do
524
+ policy "ses-policy" do
525
+ {"Statement"=>
526
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
527
+ end
528
+ end
529
+ RUBY
530
+ end
531
+
532
+ subject { client }
533
+
534
+ it do
535
+ updated = apply(subject) { delete_role_and_instance_profile_dsl }
536
+ expect(updated).to be_truthy
537
+ expected[:roles].delete("my-role")
538
+ expected[:instance_profiles].delete("my-instance-profile")
539
+ expect(export).to eq expected
540
+ end
541
+ end
222
542
  end