subiam 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.rspec +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +48 -0
- data/README.md +408 -0
- data/Rakefile +5 -0
- data/bin/subiam +189 -0
- data/lib/subiam/client.rb +565 -0
- data/lib/subiam/driver.rb +466 -0
- data/lib/subiam/dsl/context/group.rb +35 -0
- data/lib/subiam/dsl/context/managed_policy.rb +23 -0
- data/lib/subiam/dsl/context/role.rb +59 -0
- data/lib/subiam/dsl/context/user.rb +43 -0
- data/lib/subiam/dsl/context.rb +101 -0
- data/lib/subiam/dsl/converter.rb +202 -0
- data/lib/subiam/dsl/helper/arn.rb +22 -0
- data/lib/subiam/dsl.rb +9 -0
- data/lib/subiam/exporter.rb +278 -0
- data/lib/subiam/ext/array_ext.rb +13 -0
- data/lib/subiam/ext/hash_ext.rb +41 -0
- data/lib/subiam/ext/string_ext.rb +25 -0
- data/lib/subiam/logger.rb +27 -0
- data/lib/subiam/password_manager.rb +41 -0
- data/lib/subiam/template_helper.rb +20 -0
- data/lib/subiam/utils.rb +31 -0
- data/lib/subiam/version.rb +3 -0
- data/lib/subiam.rb +36 -0
- data/spec/spec_helper.rb +95 -0
- data/spec/subiam/attach_detach_policy_spec.rb +389 -0
- data/spec/subiam/create_spec.rb +271 -0
- data/spec/subiam/custom_managed_policy_spec.rb +232 -0
- data/spec/subiam/delete_spec.rb +549 -0
- data/spec/subiam/hash_ext_spec.rb +61 -0
- data/spec/subiam/ignore_login_profile_spec.rb +73 -0
- data/spec/subiam/rename_spec.rb +476 -0
- data/spec/subiam/style_spec.rb +189 -0
- data/spec/subiam/target_spec.rb +150 -0
- data/spec/subiam/update_spec.rb +911 -0
- data/subiam.gemspec +32 -0
- metadata +251 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5f32814fa2db9f3e157767104fe4da0752b40120
|
4
|
+
data.tar.gz: 677bf6d1e8fdbf6b0a9e13e7527add9ad8f8b69d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e3cc7e53244ab488c971c4f7ff583db303889cb76e951e2254174642e3a16d9663f7a009569e595101b397293fa4e9e3835236b2c055f2d4880f9f17c6ddd5f9
|
7
|
+
data.tar.gz: 6c74f7af2951620201979b7f16551724c95c8df036b47f76f8896ad0845310c7beb257b6c8ca1ad214c5f8da9017efab3989486bec2208800d9d51b8e20f3f00
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
Copyright (c) 2016 GREE, Inc.
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
Subiam is forked from Miam, which is published with the same license.
|
25
|
+
Here is the original copyright notice for Miam:
|
26
|
+
|
27
|
+
Copyright (c) 2014 Genki Sugawara
|
28
|
+
|
29
|
+
MIT License
|
30
|
+
|
31
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
32
|
+
a copy of this software and associated documentation files (the
|
33
|
+
"Software"), to deal in the Software without restriction, including
|
34
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
35
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
36
|
+
permit persons to whom the Software is furnished to do so, subject to
|
37
|
+
the following conditions:
|
38
|
+
|
39
|
+
The above copyright notice and this permission notice shall be
|
40
|
+
included in all copies or substantial portions of the Software.
|
41
|
+
|
42
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
43
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
44
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
45
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
46
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
47
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
48
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,408 @@
|
|
1
|
+
# Subiam
|
2
|
+
|
3
|
+
Subiam is a tool to manage IAM.
|
4
|
+
|
5
|
+
It defines the state of IAM using DSL, and updates IAM according to DSL.
|
6
|
+
|
7
|
+
It's forked from Miam. Miam is designed to manage all IAM entities in the AWS account. Subiam is not so. Subiam is designed to manage sub part of IAM entities in the AWS account. For example around MySQL instances / around web servers / around lambda functions / around monitoring systems.
|
8
|
+
|
9
|
+
**Notice**
|
10
|
+
* `>= 1.2.0`
|
11
|
+
* Add helper methods: `arn_policy_by_aws`, `arn_policy_by_current_account`
|
12
|
+
|
13
|
+
* `>= 1.1.0`
|
14
|
+
* Rename `require` DSL command to `import` to avoid override Kernel#require
|
15
|
+
* Allow Symbols alternative to Strings at Hash keys. It's a bit easy to write!
|
16
|
+
|
17
|
+
* `>= 1.0.0`
|
18
|
+
* Forked from miam
|
19
|
+
* Required to specify `target` in DSL or json
|
20
|
+
* `instance_profile` also follow target (bug fix)
|
21
|
+
* don't delete top level entity (user, group, role, instance_profile) by default. Use the `--enable-delete` option.
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem 'subiam'
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
|
33
|
+
$ bundle
|
34
|
+
|
35
|
+
Or install it yourself as:
|
36
|
+
|
37
|
+
$ gem install subiam
|
38
|
+
|
39
|
+
## Usage
|
40
|
+
|
41
|
+
```sh
|
42
|
+
export AWS_ACCESS_KEY_ID='...'
|
43
|
+
export AWS_SECRET_ACCESS_KEY='...'
|
44
|
+
export AWS_REGION='us-east-1'
|
45
|
+
vi subiam-xxx.rb
|
46
|
+
subiam -a --dry-run subiam-xxx.rb
|
47
|
+
subiam -a subiam-xxx.rb
|
48
|
+
```
|
49
|
+
|
50
|
+
## Help
|
51
|
+
|
52
|
+
```
|
53
|
+
Usage: subiam [options]
|
54
|
+
-p, --profile PROFILE_NAME
|
55
|
+
--credentials-path PATH
|
56
|
+
-k, --access-key ACCESS_KEY
|
57
|
+
-s, --secret-key SECRET_KEY
|
58
|
+
-r, --region REGION
|
59
|
+
-a, --apply
|
60
|
+
-f, --file FILE
|
61
|
+
--dry-run
|
62
|
+
--account-output FILE
|
63
|
+
-e, --export
|
64
|
+
-o, --output FILE
|
65
|
+
--split
|
66
|
+
--split-more
|
67
|
+
--format=FORMAT
|
68
|
+
--export-concurrency N
|
69
|
+
--ignore-login-profile
|
70
|
+
--no-color
|
71
|
+
--no-progress
|
72
|
+
--debug
|
73
|
+
--enable-delete
|
74
|
+
```
|
75
|
+
|
76
|
+
## IAM definition files example
|
77
|
+
subiam_mytool.rb
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
import 'subiam_ec2_assume_role_attrs.rb'
|
81
|
+
|
82
|
+
target /^mytool/ # required!!!
|
83
|
+
|
84
|
+
role 'mytool', path: '/' do
|
85
|
+
context.version = '2012-10-17'
|
86
|
+
|
87
|
+
include_template 'ec2-assume-role-attrs'
|
88
|
+
|
89
|
+
instance_profiles(
|
90
|
+
'mytool'
|
91
|
+
)
|
92
|
+
|
93
|
+
policy 'mytool-role-policy' do
|
94
|
+
{
|
95
|
+
Version: context.version,
|
96
|
+
Statement: [
|
97
|
+
{
|
98
|
+
Effect: "Allow",
|
99
|
+
Action: [
|
100
|
+
"ec2:DescribeInstances",
|
101
|
+
"ec2:DescribeVpcs"
|
102
|
+
],
|
103
|
+
Resource: [
|
104
|
+
"*"
|
105
|
+
]
|
106
|
+
},
|
107
|
+
{
|
108
|
+
Effect: "Allow",
|
109
|
+
Action: [
|
110
|
+
"route53:Get*",
|
111
|
+
"route53:List*",
|
112
|
+
"route53:ChangeResourceRecordSets*"
|
113
|
+
],
|
114
|
+
Resource: [
|
115
|
+
"*"
|
116
|
+
]
|
117
|
+
},
|
118
|
+
],
|
119
|
+
}
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
instance_profile 'mytool', path: '/'
|
124
|
+
|
125
|
+
```
|
126
|
+
|
127
|
+
subiam_ec2_assume_role_attrs.rb
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
template "ec2-assume-role-attrs" do
|
131
|
+
assume_role_policy_document do
|
132
|
+
{
|
133
|
+
Version: context.version,
|
134
|
+
Statement: [
|
135
|
+
{
|
136
|
+
Sid: "",
|
137
|
+
Effect: "Allow",
|
138
|
+
Principal: {Service: "ec2.amazonaws.com"},
|
139
|
+
Action: "sts:AssumeRole",
|
140
|
+
},
|
141
|
+
],
|
142
|
+
}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
147
|
+
|
148
|
+
## Use management policy
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
user "foo", path: '/' do
|
152
|
+
attached_managed_policies(
|
153
|
+
'arn:aws:iam::0123456789:policy/MyPolicy',
|
154
|
+
|
155
|
+
arn_policy_by_current_account("MyPolicy2"),
|
156
|
+
# == "arn:aws:iam::0123456789:policy/MyPolicy2'
|
157
|
+
|
158
|
+
arn_policy_by_aws("AdministratorAccess")
|
159
|
+
# == 'arn:aws:iam::aws:policy/AdministratorAccess'
|
160
|
+
)
|
161
|
+
end
|
162
|
+
```
|
163
|
+
|
164
|
+
|
165
|
+
---
|
166
|
+
old examples (but works if add `target`)
|
167
|
+
|
168
|
+
```ruby
|
169
|
+
import 'other/iamfile'
|
170
|
+
|
171
|
+
target /^monitoring-/
|
172
|
+
|
173
|
+
user "monitoring-bob", :path => "/monitoring-user/" do
|
174
|
+
login_profile :password_reset_required=>true
|
175
|
+
|
176
|
+
groups(
|
177
|
+
"Admin"
|
178
|
+
)
|
179
|
+
|
180
|
+
policy "bob-policy" do
|
181
|
+
{"Version"=>"2012-10-17",
|
182
|
+
"Statement"=>
|
183
|
+
[{"Action"=>
|
184
|
+
["s3:Get*",
|
185
|
+
"s3:List*"],
|
186
|
+
"Effect"=>"Allow",
|
187
|
+
"Resource"=>"*"}]}
|
188
|
+
end
|
189
|
+
|
190
|
+
attached_managed_policies(
|
191
|
+
# attached_managed_policy
|
192
|
+
)
|
193
|
+
end
|
194
|
+
|
195
|
+
user "mary", :path => "/staff/" do
|
196
|
+
# login_profile :password_reset_required=>true
|
197
|
+
|
198
|
+
groups(
|
199
|
+
# no group
|
200
|
+
)
|
201
|
+
|
202
|
+
policy "s3-readonly" do
|
203
|
+
{"Version"=>"2012-10-17",
|
204
|
+
"Statement"=>
|
205
|
+
[{"Action"=>
|
206
|
+
["s3:Get*",
|
207
|
+
"s3:List*"],
|
208
|
+
"Effect"=>"Allow",
|
209
|
+
"Resource"=>"*"}]}
|
210
|
+
end
|
211
|
+
|
212
|
+
policy "route53-readonly" do
|
213
|
+
{"Version"=>"2012-10-17",
|
214
|
+
"Statement"=>
|
215
|
+
[{"Action"=>
|
216
|
+
["route53:Get*",
|
217
|
+
"route53:List*"],
|
218
|
+
"Effect"=>"Allow",
|
219
|
+
"Resource"=>"*"}]}
|
220
|
+
end
|
221
|
+
|
222
|
+
attached_managed_policies(
|
223
|
+
"arn:aws:iam::aws:policy/AdministratorAccess",
|
224
|
+
"arn:aws:iam::123456789012:policy/my_policy"
|
225
|
+
)
|
226
|
+
end
|
227
|
+
|
228
|
+
group "Admin", :path => "/admin/" do
|
229
|
+
policy "Admin" do
|
230
|
+
{"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
role "S3", :path => "/" do
|
235
|
+
instance_profiles(
|
236
|
+
"S3"
|
237
|
+
)
|
238
|
+
|
239
|
+
assume_role_policy_document do
|
240
|
+
{"Version"=>"2012-10-17",
|
241
|
+
"Statement"=>
|
242
|
+
[{"Sid"=>"",
|
243
|
+
"Effect"=>"Allow",
|
244
|
+
"Principal"=>{"Service"=>"ec2.amazonaws.com"},
|
245
|
+
"Action"=>"sts:AssumeRole"}]}
|
246
|
+
end
|
247
|
+
|
248
|
+
policy "S3-role-policy" do
|
249
|
+
{"Version"=>"2012-10-17",
|
250
|
+
"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
instance_profile "S3", :path => "/"
|
255
|
+
```
|
256
|
+
|
257
|
+
## Rename
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
import 'other/iamfile'
|
261
|
+
|
262
|
+
user "bob2", :path => "/developer/", :renamed_from => "bob" do
|
263
|
+
# ...
|
264
|
+
end
|
265
|
+
|
266
|
+
group "Admin2", :path => "/admin/". :renamed_from => "Admin" do
|
267
|
+
# ...
|
268
|
+
end
|
269
|
+
```
|
270
|
+
|
271
|
+
## Managed Policy attach/detach
|
272
|
+
|
273
|
+
```ruby
|
274
|
+
user "bob", :path => "/developer/" do
|
275
|
+
login_profile :password_reset_required=>true
|
276
|
+
|
277
|
+
groups(
|
278
|
+
"Admin"
|
279
|
+
)
|
280
|
+
|
281
|
+
policy "bob-policy" do
|
282
|
+
# ...
|
283
|
+
end
|
284
|
+
|
285
|
+
attached_managed_policies(
|
286
|
+
"arn:aws:iam::aws:policy/AmazonElastiCacheReadOnlyAccess"
|
287
|
+
)
|
288
|
+
end
|
289
|
+
```
|
290
|
+
|
291
|
+
## Custom Managed Policy
|
292
|
+
|
293
|
+
```ruby
|
294
|
+
managed_policy "my-policy", :path=>"/" do
|
295
|
+
{"Version"=>"2012-10-17",
|
296
|
+
"Statement"=>
|
297
|
+
[{"Effect"=>"Allow", "Action"=>"directconnect:Describe*", "Resource"=>"*"}]}
|
298
|
+
end
|
299
|
+
|
300
|
+
user "bob", :path => "/developer/" do
|
301
|
+
login_profile :password_reset_required=>true
|
302
|
+
|
303
|
+
groups(
|
304
|
+
"Admin"
|
305
|
+
)
|
306
|
+
|
307
|
+
policy "bob-policy" do
|
308
|
+
# ...
|
309
|
+
end
|
310
|
+
|
311
|
+
attached_managed_policies(
|
312
|
+
"arn:aws:iam::123456789012:policy/my-policy"
|
313
|
+
)
|
314
|
+
end
|
315
|
+
```
|
316
|
+
|
317
|
+
## Use JSON
|
318
|
+
|
319
|
+
```sh
|
320
|
+
$ subiam -e -o iam.json
|
321
|
+
ᗧ 100%
|
322
|
+
Export IAM to `iam.json`
|
323
|
+
|
324
|
+
$ cat iam.json
|
325
|
+
{
|
326
|
+
"users": {
|
327
|
+
"bob": {
|
328
|
+
"path": "/",
|
329
|
+
"groups": [
|
330
|
+
"Admin"
|
331
|
+
],
|
332
|
+
"policies": {
|
333
|
+
...
|
334
|
+
|
335
|
+
$ subiam -a -f iam.json --dry-run
|
336
|
+
Apply `iam.json` to IAM (dry-run)
|
337
|
+
ᗧ 100%
|
338
|
+
No change
|
339
|
+
```
|
340
|
+
|
341
|
+
## Use Template
|
342
|
+
|
343
|
+
```ruby
|
344
|
+
template "common-policy" do
|
345
|
+
policy "my-policy" do
|
346
|
+
{"Version"=>context.version,
|
347
|
+
"Statement"=>
|
348
|
+
[{"Action"=>
|
349
|
+
["s3:Get*",
|
350
|
+
"s3:List*"],
|
351
|
+
"Effect"=>"Allow",
|
352
|
+
"Resource"=>"*"}]}
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
template "common-role-attrs" do
|
357
|
+
assume_role_policy_document do
|
358
|
+
{"Version"=>context.version,
|
359
|
+
"Statement"=>
|
360
|
+
[{"Sid"=>"",
|
361
|
+
"Effect"=>"Allow",
|
362
|
+
"Principal"=>{"Service"=>"ec2.amazonaws.com"},
|
363
|
+
"Action"=>"sts:AssumeRole"}]}
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
user "bob", :path => "/developer/" do
|
368
|
+
login_profile :password_reset_required=>true
|
369
|
+
|
370
|
+
groups(
|
371
|
+
"Admin"
|
372
|
+
)
|
373
|
+
|
374
|
+
include_template "common-policy", version: "2012-10-17"
|
375
|
+
end
|
376
|
+
|
377
|
+
user "mary", :path => "/staff/" do
|
378
|
+
# login_profile :password_reset_required=>true
|
379
|
+
|
380
|
+
groups(
|
381
|
+
# no group
|
382
|
+
)
|
383
|
+
|
384
|
+
context.version = "2012-10-17"
|
385
|
+
include_template "common-policy"
|
386
|
+
|
387
|
+
attached_managed_policies(
|
388
|
+
"arn:aws:iam::aws:policy/AdministratorAccess",
|
389
|
+
"arn:aws:iam::123456789012:policy/my_policy"
|
390
|
+
)
|
391
|
+
end
|
392
|
+
|
393
|
+
role "S3", :path => "/" do
|
394
|
+
instance_profiles(
|
395
|
+
"S3"
|
396
|
+
)
|
397
|
+
|
398
|
+
include_template "common-role-attrs"
|
399
|
+
|
400
|
+
policy "S3-role-policy" do
|
401
|
+
{"Version"=>"2012-10-17",
|
402
|
+
"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
|
403
|
+
end
|
404
|
+
end
|
405
|
+
```
|
406
|
+
|
407
|
+
## Similar tools
|
408
|
+
* [Codenize.tools](http://codenize.tools/)
|
data/Rakefile
ADDED
data/bin/subiam
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
$: << File.expand_path("#{File.dirname __FILE__}/../lib")
|
3
|
+
require 'rubygems'
|
4
|
+
require 'subiam'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
Version = Subiam::VERSION
|
9
|
+
DEFAULT_FILENAME = 'IAMfile'
|
10
|
+
|
11
|
+
mode = nil
|
12
|
+
file = DEFAULT_FILENAME
|
13
|
+
output_file = '-'
|
14
|
+
account_output = 'account.csv'
|
15
|
+
split = false
|
16
|
+
MAGIC_COMMENT = <<-EOS
|
17
|
+
# -*- mode: ruby -*-
|
18
|
+
# vi: set ft=ruby :
|
19
|
+
EOS
|
20
|
+
|
21
|
+
options = {
|
22
|
+
:dry_run => false,
|
23
|
+
:format => :ruby,
|
24
|
+
:color => true,
|
25
|
+
:debug => false,
|
26
|
+
}
|
27
|
+
|
28
|
+
options[:password_manager] = Subiam::PasswordManager.new(account_output, options)
|
29
|
+
|
30
|
+
ARGV.options do |opt|
|
31
|
+
begin
|
32
|
+
access_key = nil
|
33
|
+
secret_key = nil
|
34
|
+
region = nil
|
35
|
+
profile_name = nil
|
36
|
+
credentials_path = nil
|
37
|
+
format_passed = false
|
38
|
+
|
39
|
+
opt.on('-p', '--profile PROFILE_NAME') {|v| profile_name = v }
|
40
|
+
opt.on('' , '--credentials-path PATH') {|v| credentials_path = v }
|
41
|
+
opt.on('-k', '--access-key ACCESS_KEY') {|v| access_key = v }
|
42
|
+
opt.on('-s', '--secret-key SECRET_KEY') {|v| secret_key = v }
|
43
|
+
opt.on('-r', '--region REGION') {|v| region = v }
|
44
|
+
opt.on('-a', '--apply') { mode = :apply }
|
45
|
+
opt.on('-f', '--file FILE') {|v| file = v }
|
46
|
+
opt.on('' , '--dry-run') { options[:dry_run] = true }
|
47
|
+
opt.on('' , '--account-output FILE') {|v| options[:password_manager] = Subiam::PasswordManager.new(v, options) }
|
48
|
+
opt.on('-e', '--export') { mode = :export }
|
49
|
+
opt.on('-o', '--output FILE') {|v| output_file = v }
|
50
|
+
opt.on('' , '--split') { split = true }
|
51
|
+
opt.on('' , '--split-more') { split = :more }
|
52
|
+
opt.on('', '--format=FORMAT', [:ruby, :json]) {|v| format_passed = true; options[:format] = v }
|
53
|
+
opt.on('' , '--export-concurrency N', Integer) {|v| options[:export_concurrency] = v }
|
54
|
+
opt.on('' , '--ignore-login-profile') { options[:ignore_login_profile] = true }
|
55
|
+
opt.on('' , '--no-color') { options[:color] = false }
|
56
|
+
opt.on('' , '--no-progress') { options[:no_progress] = true }
|
57
|
+
opt.on('' , '--debug') { options[:debug] = true }
|
58
|
+
opt.on('' , '--enable-delete') { options[:enable_delete] = true }
|
59
|
+
opt.parse!
|
60
|
+
|
61
|
+
aws_opts = {}
|
62
|
+
|
63
|
+
if access_key and secret_key
|
64
|
+
aws_opts.update(
|
65
|
+
:access_key_id => access_key,
|
66
|
+
:secret_access_key => secret_key
|
67
|
+
)
|
68
|
+
elsif profile_name or credentials_path
|
69
|
+
credentials_opts = {}
|
70
|
+
credentials_opts[:profile_name] = profile_name if profile_name
|
71
|
+
credentials_opts[:path] = credentials_path if credentials_path
|
72
|
+
credentials = Aws::SharedCredentials.new(credentials_opts)
|
73
|
+
aws_opts[:credentials] = credentials
|
74
|
+
elsif (access_key and !secret_key) or (!access_key and secret_key) or mode.nil?
|
75
|
+
puts opt.help
|
76
|
+
exit 1
|
77
|
+
end
|
78
|
+
|
79
|
+
aws_opts[:region] = region if region
|
80
|
+
Aws.config.update(aws_opts)
|
81
|
+
|
82
|
+
if not format_passed and [file, output_file].any? {|i| i =~ /\.json\z/ }
|
83
|
+
options[:format] = :json
|
84
|
+
end
|
85
|
+
rescue => e
|
86
|
+
$stderr.puts("[ERROR] #{e.message}")
|
87
|
+
exit 1
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
String.colorize = options[:color]
|
92
|
+
|
93
|
+
if options[:debug]
|
94
|
+
Aws.config.update(
|
95
|
+
:http_wire_trace => true,
|
96
|
+
:logger => Subiam::Logger.instance
|
97
|
+
)
|
98
|
+
end
|
99
|
+
|
100
|
+
begin
|
101
|
+
logger = Subiam::Logger.instance
|
102
|
+
logger.set_debug(options[:debug])
|
103
|
+
client = Subiam::Client.new(options)
|
104
|
+
|
105
|
+
case mode
|
106
|
+
when :export
|
107
|
+
if split
|
108
|
+
logger.info('Export IAM')
|
109
|
+
output_file = DEFAULT_FILENAME if output_file == '-'
|
110
|
+
requires = []
|
111
|
+
|
112
|
+
client.export(:split_more => (split == :more), :convert => (options[:format] == :ruby)) do |args|
|
113
|
+
type, dsl = args.values_at(:type, :dsl)
|
114
|
+
next if dsl.empty?
|
115
|
+
|
116
|
+
type = type.to_s
|
117
|
+
dir = File.dirname(output_file)
|
118
|
+
|
119
|
+
if split == :more
|
120
|
+
name = args[:name]
|
121
|
+
dir = File.join(dir, type)
|
122
|
+
FileUtils.mkdir_p(dir)
|
123
|
+
iam_filename = "#{name}.iam"
|
124
|
+
iam_file = File.join(dir, iam_filename)
|
125
|
+
requires << File.join(type, iam_filename)
|
126
|
+
else
|
127
|
+
iam_filename = "#{type}.iam"
|
128
|
+
iam_file = File.join(dir, iam_filename)
|
129
|
+
requires << iam_filename
|
130
|
+
end
|
131
|
+
|
132
|
+
if options[:format] == :json
|
133
|
+
iam_file << '.json'
|
134
|
+
end
|
135
|
+
|
136
|
+
logger.info(" write `#{iam_file}`")
|
137
|
+
|
138
|
+
open(iam_file, 'wb') do |f|
|
139
|
+
f.puts MAGIC_COMMENT if options[:format] == :ruby
|
140
|
+
f.puts dsl
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
if options[:format] == :ruby
|
145
|
+
logger.info(" write `#{output_file}`")
|
146
|
+
|
147
|
+
open(output_file, 'wb') do |f|
|
148
|
+
f.puts MAGIC_COMMENT
|
149
|
+
|
150
|
+
requires.each do |iam_file|
|
151
|
+
f.puts "require '#{iam_file}'"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
else
|
156
|
+
exported = client.export(:convert => (options[:format] == :ruby))
|
157
|
+
|
158
|
+
if output_file == '-'
|
159
|
+
logger.info('# Export IAM')
|
160
|
+
puts exported
|
161
|
+
else
|
162
|
+
logger.info("Export IAM to `#{output_file}`")
|
163
|
+
open(output_file, 'wb') do |f|
|
164
|
+
f.puts MAGIC_COMMENT if options[:format] == :ruby
|
165
|
+
f.puts exported
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
when :apply
|
170
|
+
unless File.exist?(file)
|
171
|
+
raise "No IAMfile found (looking for: #{file})"
|
172
|
+
end
|
173
|
+
|
174
|
+
msg = "Apply `#{file}` to IAM"
|
175
|
+
msg << ' (dry-run)' if options[:dry_run]
|
176
|
+
logger.info(msg)
|
177
|
+
|
178
|
+
updated = client.apply(file)
|
179
|
+
|
180
|
+
logger.info('No change'.intense_blue) unless updated
|
181
|
+
end
|
182
|
+
rescue => e
|
183
|
+
if options[:debug]
|
184
|
+
raise e
|
185
|
+
else
|
186
|
+
$stderr.puts("[ERROR] #{e.message}".red)
|
187
|
+
exit 1
|
188
|
+
end
|
189
|
+
end
|