miam 0.1.0.beta → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 78a6357ad96eb46c37e14554170823849a1b7299
4
- data.tar.gz: 5e8e8b62d90cfa1d313874b5d842a505bb07bcfe
3
+ metadata.gz: 1c277e2932203a2740972ef45fb3588f25e08ced
4
+ data.tar.gz: 560435cc28118cc841397919249697a68a2e6851
5
5
  SHA512:
6
- metadata.gz: 2bbe33cd3fc4274a239bfde9bff8eee340af294178b873f9b3f1c533a5efd02f0a41a960ee8d752f54c252eadba21a3f2a1484f939a94e16c96690e173e8ee3f
7
- data.tar.gz: aa09af7d99890cd20908d5f6991846978bc40fcdf007e2cc7b152e72f81f13e49b00b9120646e34524ec95e66bc863a12b5586c49d54518146e4593fa8d01382
6
+ metadata.gz: f631ea1267d5c62723f85129e26508dc712b5189ea53e47ada4aacbcbc4b75f22bf56971364dc7490734343d2e62d885a6bbf68636d622550495a35bda2585b5
7
+ data.tar.gz: fa71e40019ca1342ec1472c07c1ae376b4233e1bda0129ed3715e9c151c751b43d1339e08f11018752ab080ed6cec1debcc79bc9a7104891f13f6eb99c4b3490
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --require rspec/instafail
2
+ --format RSpec::Instafail
3
+ --colour
4
+ --require spec_helper
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script:
5
+ - bundle install
6
+ - bundle exec rake
7
+ env:
8
+ global:
9
+ - secure: "Ec8bwSfp06anSzLJpGhkKjPz9EocMwl7H8t2LKoI3bKV/cz9JU0GhhUdUUmg3mCFH9+8/YGLzcbFKcxZIqnDK7ukdgTGsnGDevnctis0QwM7/nKHdkaK8JWhCx41TUXOqoiCKkNEnm1EbDtrILt4rJwb0BGXGnPjv6nLAyvdE2Y="
10
+ - secure: "Ky5Dpxc7SIqbQ4Y10m/jik/rVdeGMeh1439m3KB+tiV/Bz1hhWv4+If150ajLjbmWCZBPMLhxrTL0EePoyqYXpOGHvINvYM+/XCPcpP4iYkaTzr1MVIOMpa8A8aAOOgQWoGOwfyWoxfrYzv/TRvtMietnm+dZwVcbbkQ4ut7oa4="
11
+ - AWS_REGION=ap-northeast-1
data/README.md CHANGED
@@ -4,6 +4,10 @@ Miam is a tool to manage IAM.
4
4
 
5
5
  It defines the state of IAM using DSL, and updates IAM according to DSL.
6
6
 
7
+ [![Gem Version](https://badge.fury.io/rb/miam.svg)](http://badge.fury.io/rb/miam)
8
+ [![Build Status](https://travis-ci.org/winebarrel/miam.svg?branch=master)](https://travis-ci.org/winebarrel/miam)
9
+ [![Coverage Status](https://coveralls.io/repos/winebarrel/miam/badge.png?branch=master)](https://coveralls.io/r/winebarrel/miam?branch=master)
10
+
7
11
  ## Installation
8
12
 
9
13
  Add this line to your application's Gemfile:
@@ -18,7 +22,7 @@ And then execute:
18
22
 
19
23
  Or install it yourself as:
20
24
 
21
- $ gem install miam --pre
25
+ $ gem install miam
22
26
 
23
27
  ## Usage
24
28
 
@@ -58,7 +62,7 @@ Usage: miam [options]
58
62
  ```ruby
59
63
  require 'other/iamfile'
60
64
 
61
- user "bob", path: "/developer/" do
65
+ user "bob", :path => "/developer/" do
62
66
  login_profile password_reset_required: true
63
67
 
64
68
  groups(
@@ -76,7 +80,7 @@ user "bob", path: "/developer/" do
76
80
  end
77
81
  end
78
82
 
79
- user "mary", path: "/staff/" do
83
+ user "mary", :path => "/staff/" do
80
84
  # login_profile password_reset_required: true
81
85
 
82
86
  groups(
@@ -104,9 +108,23 @@ user "mary", path: "/staff/" do
104
108
  end
105
109
  end
106
110
 
107
- group "Admin", path: "/admin/" do
111
+ group "Admin", :path => "/admin/" do
108
112
  policy "Admin" do
109
113
  {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
110
114
  end
111
115
  end
112
116
  ```
117
+
118
+ ## Rename
119
+
120
+ ```ruby
121
+ require 'other/iamfile'
122
+
123
+ user "bob2", :path => "/developer/", :renamed_from => "bob" do
124
+ # ...
125
+ end
126
+
127
+ group "Admin2", :path => "/admin/". :renamed_from => "Admin" do
128
+ # ...
129
+ end
130
+ ```
data/Rakefile CHANGED
@@ -1,2 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
2
3
 
4
+ RSpec::Core::RakeTask.new('spec')
5
+ task :default => :spec
@@ -53,6 +53,7 @@ class Miam::Client
53
53
  actual_attrs = actual.delete(user_name)
54
54
 
55
55
  if actual_attrs
56
+ updated = walk_path(:user, user_name, expected_attrs[:path], actual_attrs[:path]) || updated
56
57
  updated = walk_user(user_name, expected_attrs, actual_attrs) || updated
57
58
  else
58
59
  actual_attrs = @driver.create_user(user_name, expected_attrs)
@@ -83,7 +84,7 @@ class Miam::Client
83
84
  def walk_user(user_name, expected_attrs, actual_attrs)
84
85
  updated = walk_login_profile(user_name, expected_attrs[:login_profile], actual_attrs[:login_profile])
85
86
  updated = walk_user_groups(user_name, expected_attrs[:groups], actual_attrs[:groups]) || updated
86
- walk_policies(:user, user_name, expected_attrs[:policies], actual_attrs[:policies])
87
+ walk_policies(:user, user_name, expected_attrs[:policies], actual_attrs[:policies]) || updated
87
88
  end
88
89
 
89
90
  def walk_login_profile(user_name, expected_login_profile, actual_login_profile)
@@ -1,3 +1,3 @@
1
1
  module Miam
2
- VERSION = '0.1.0.beta'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -25,4 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.add_dependency 'term-ansicolor'
26
26
  spec.add_development_dependency 'bundler', '~> 1.7'
27
27
  spec.add_development_dependency 'rake', '~> 10.0'
28
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
29
+ spec.add_development_dependency 'rspec-instafail'
30
+ spec.add_development_dependency 'coveralls'
28
31
  end
@@ -0,0 +1,114 @@
1
+ describe 'create' do
2
+ context 'when empty' do
3
+ subject { client }
4
+
5
+ it do
6
+ updated = apply(subject) { '' }
7
+ expect(updated).to be_falsey
8
+ expect(export).to eq({:users=>{}, :groups=>{}})
9
+ end
10
+ end
11
+
12
+ context 'when create user and group' do
13
+ let(:dsl) do
14
+ <<-RUBY
15
+ user "bob", :path=>"/devloper/" do
16
+ login_profile :password_reset_required=>true
17
+
18
+ groups(
19
+ "Admin",
20
+ "SES"
21
+ )
22
+
23
+ policy "S3" do
24
+ {"Statement"=>
25
+ [{"Action"=>
26
+ ["s3:Get*",
27
+ "s3:List*"],
28
+ "Effect"=>"Allow",
29
+ "Resource"=>"*"}]}
30
+ end
31
+ end
32
+
33
+ user "mary", :path=>"/staff/" do
34
+ policy "S3" do
35
+ {"Statement"=>
36
+ [{"Action"=>
37
+ ["s3:Get*",
38
+ "s3:List*"],
39
+ "Effect"=>"Allow",
40
+ "Resource"=>"*"}]}
41
+ end
42
+ end
43
+
44
+ group "Admin", :path=>"/admin/" do
45
+ policy "Admin" do
46
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
47
+ end
48
+ end
49
+
50
+ group "SES", :path=>"/ses/" do
51
+ policy "ses-policy" do
52
+ {"Statement"=>
53
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
54
+ end
55
+ end
56
+ RUBY
57
+ end
58
+
59
+ context 'when apply' do
60
+ subject { client }
61
+
62
+ it do
63
+ updated = apply(subject) { dsl }
64
+ expect(updated).to be_truthy
65
+ expect(export).to eq(
66
+ {:users=>
67
+ {"bob"=>
68
+ {:path=>"/devloper/",
69
+ :groups=>["Admin", "SES"],
70
+ :policies=>
71
+ {"S3"=>
72
+ {"Statement"=>
73
+ [{"Action"=>["s3:Get*", "s3:List*"],
74
+ "Effect"=>"Allow",
75
+ "Resource"=>"*"}]}},
76
+ :login_profile=>{:password_reset_required=>true}},
77
+ "mary"=>
78
+ {:path=>"/staff/",
79
+ :groups=>[],
80
+ :policies=>
81
+ {"S3"=>
82
+ {"Statement"=>
83
+ [{"Action"=>["s3:Get*", "s3:List*"],
84
+ "Effect"=>"Allow",
85
+ "Resource"=>"*"}]}}}},
86
+ :groups=>
87
+ {"Admin"=>
88
+ {:path=>"/admin/",
89
+ :policies=>
90
+ {"Admin"=>
91
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}}},
92
+ "SES"=>
93
+ {:path=>"/ses/",
94
+ :policies=>
95
+ {"ses-policy"=>
96
+ {"Statement"=>
97
+ [{"Effect"=>"Allow",
98
+ "Action"=>"ses:SendRawEmail",
99
+ "Resource"=>"*"}]}}}}}
100
+ )
101
+ end
102
+ end
103
+
104
+ context 'when dry-run' do
105
+ subject { client(dry_run: true) }
106
+
107
+ it do
108
+ updated = apply(subject) { dsl }
109
+ expect(updated).to be_falsey
110
+ expect(export).to eq({:users=>{}, :groups=>{}})
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,222 @@
1
+ describe 'delete' do
2
+ let(:dsl) do
3
+ <<-RUBY
4
+ user "bob", :path=>"/devloper/" do
5
+ login_profile :password_reset_required=>true
6
+
7
+ groups(
8
+ "Admin",
9
+ "SES"
10
+ )
11
+
12
+ policy "S3" do
13
+ {"Statement"=>
14
+ [{"Action"=>
15
+ ["s3:Get*",
16
+ "s3:List*"],
17
+ "Effect"=>"Allow",
18
+ "Resource"=>"*"}]}
19
+ end
20
+ end
21
+
22
+ user "mary", :path=>"/staff/" do
23
+ policy "S3" do
24
+ {"Statement"=>
25
+ [{"Action"=>
26
+ ["s3:Get*",
27
+ "s3:List*"],
28
+ "Effect"=>"Allow",
29
+ "Resource"=>"*"}]}
30
+ end
31
+ end
32
+
33
+ group "Admin", :path=>"/admin/" do
34
+ policy "Admin" do
35
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
36
+ end
37
+ end
38
+
39
+ group "SES", :path=>"/ses/" do
40
+ policy "ses-policy" do
41
+ {"Statement"=>
42
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
43
+ end
44
+ end
45
+ RUBY
46
+ end
47
+
48
+ let(:expected) do
49
+ {:users=>
50
+ {"bob"=>
51
+ {:path=>"/devloper/",
52
+ :groups=>["Admin", "SES"],
53
+ :policies=>
54
+ {"S3"=>
55
+ {"Statement"=>
56
+ [{"Action"=>["s3:Get*", "s3:List*"],
57
+ "Effect"=>"Allow",
58
+ "Resource"=>"*"}]}},
59
+ :login_profile=>{:password_reset_required=>true}},
60
+ "mary"=>
61
+ {:path=>"/staff/",
62
+ :groups=>[],
63
+ :policies=>
64
+ {"S3"=>
65
+ {"Statement"=>
66
+ [{"Action"=>["s3:Get*", "s3:List*"],
67
+ "Effect"=>"Allow",
68
+ "Resource"=>"*"}]}}}},
69
+ :groups=>
70
+ {"Admin"=>
71
+ {:path=>"/admin/",
72
+ :policies=>
73
+ {"Admin"=>
74
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}}},
75
+ "SES"=>
76
+ {:path=>"/ses/",
77
+ :policies=>
78
+ {"ses-policy"=>
79
+ {"Statement"=>
80
+ [{"Effect"=>"Allow",
81
+ "Action"=>"ses:SendRawEmail",
82
+ "Resource"=>"*"}]}}}}}
83
+ end
84
+
85
+ before(:each) do
86
+ apply { dsl }
87
+ end
88
+
89
+ context 'when delete group' do
90
+ let(:delete_group_dsl) do
91
+ <<-RUBY
92
+ user "bob", :path=>"/devloper/" do
93
+ login_profile :password_reset_required=>true
94
+
95
+ groups(
96
+ "Admin"
97
+ )
98
+
99
+ policy "S3" do
100
+ {"Statement"=>
101
+ [{"Action"=>
102
+ ["s3:Get*",
103
+ "s3:List*"],
104
+ "Effect"=>"Allow",
105
+ "Resource"=>"*"}]}
106
+ end
107
+ end
108
+
109
+ user "mary", :path=>"/staff/" do
110
+ policy "S3" do
111
+ {"Statement"=>
112
+ [{"Action"=>
113
+ ["s3:Get*",
114
+ "s3:List*"],
115
+ "Effect"=>"Allow",
116
+ "Resource"=>"*"}]}
117
+ end
118
+ end
119
+
120
+ group "Admin", :path=>"/admin/" do
121
+ policy "Admin" do
122
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
123
+ end
124
+ end
125
+ RUBY
126
+ end
127
+
128
+ subject { client }
129
+
130
+ it do
131
+ updated = apply(subject) { delete_group_dsl }
132
+ expect(updated).to be_truthy
133
+ expected[:users]["bob"][:groups] = ["Admin"]
134
+ expected[:groups].delete("SES")
135
+ expect(export).to eq expected
136
+ end
137
+ end
138
+
139
+ context 'when delete user' do
140
+ let(:delete_user_dsl) do
141
+ <<-RUBY
142
+ user "mary", :path=>"/staff/" do
143
+ policy "S3" do
144
+ {"Statement"=>
145
+ [{"Action"=>
146
+ ["s3:Get*",
147
+ "s3:List*"],
148
+ "Effect"=>"Allow",
149
+ "Resource"=>"*"}]}
150
+ end
151
+ end
152
+
153
+ group "Admin", :path=>"/admin/" do
154
+ policy "Admin" do
155
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
156
+ end
157
+ end
158
+
159
+ group "SES", :path=>"/ses/" do
160
+ policy "ses-policy" do
161
+ {"Statement"=>
162
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
163
+ end
164
+ end
165
+ RUBY
166
+ end
167
+
168
+ subject { client }
169
+
170
+ it do
171
+ updated = apply(subject) { delete_user_dsl }
172
+ expect(updated).to be_truthy
173
+ expected[:users].delete("bob")
174
+ expect(export).to eq expected
175
+ end
176
+ end
177
+
178
+ context 'when delete user_and_group' do
179
+ let(:delete_user_and_group_dsl) do
180
+ <<-RUBY
181
+ user "mary", :path=>"/staff/" do
182
+ policy "S3" do
183
+ {"Statement"=>
184
+ [{"Action"=>
185
+ ["s3:Get*",
186
+ "s3:List*"],
187
+ "Effect"=>"Allow",
188
+ "Resource"=>"*"}]}
189
+ end
190
+ end
191
+
192
+ group "Admin", :path=>"/admin/" do
193
+ policy "Admin" do
194
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
195
+ end
196
+ end
197
+ RUBY
198
+ end
199
+
200
+ context 'when apply' do
201
+ subject { client }
202
+
203
+ it do
204
+ updated = apply(subject) { delete_user_and_group_dsl }
205
+ expect(updated).to be_truthy
206
+ expected[:users].delete("bob")
207
+ expected[:groups].delete("SES")
208
+ expect(export).to eq expected
209
+ end
210
+ end
211
+
212
+ context 'when dry-run' do
213
+ subject { client(dry_run: true) }
214
+
215
+ it do
216
+ updated = apply(subject) { delete_user_and_group_dsl }
217
+ expect(updated).to be_falsey
218
+ expect(export).to eq expected
219
+ end
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,262 @@
1
+ describe 'update' do
2
+ let(:dsl) do
3
+ <<-RUBY
4
+ user "bob", :path=>"/devloper/" do
5
+ login_profile :password_reset_required=>true
6
+
7
+ groups(
8
+ "Admin",
9
+ "SES"
10
+ )
11
+
12
+ policy "S3" do
13
+ {"Statement"=>
14
+ [{"Action"=>
15
+ ["s3:Get*",
16
+ "s3:List*"],
17
+ "Effect"=>"Allow",
18
+ "Resource"=>"*"}]}
19
+ end
20
+ end
21
+
22
+ user "mary", :path=>"/staff/" do
23
+ policy "S3" do
24
+ {"Statement"=>
25
+ [{"Action"=>
26
+ ["s3:Get*",
27
+ "s3:List*"],
28
+ "Effect"=>"Allow",
29
+ "Resource"=>"*"}]}
30
+ end
31
+ end
32
+
33
+ group "Admin", :path=>"/admin/" do
34
+ policy "Admin" do
35
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
36
+ end
37
+ end
38
+
39
+ group "SES", :path=>"/ses/" do
40
+ policy "ses-policy" do
41
+ {"Statement"=>
42
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
43
+ end
44
+ end
45
+ RUBY
46
+ end
47
+
48
+ let(:expected) do
49
+ {:users=>
50
+ {"bob"=>
51
+ {:path=>"/devloper/",
52
+ :groups=>["Admin", "SES"],
53
+ :policies=>
54
+ {"S3"=>
55
+ {"Statement"=>
56
+ [{"Action"=>["s3:Get*", "s3:List*"],
57
+ "Effect"=>"Allow",
58
+ "Resource"=>"*"}]}},
59
+ :login_profile=>{:password_reset_required=>true}},
60
+ "mary"=>
61
+ {:path=>"/staff/",
62
+ :groups=>[],
63
+ :policies=>
64
+ {"S3"=>
65
+ {"Statement"=>
66
+ [{"Action"=>["s3:Get*", "s3:List*"],
67
+ "Effect"=>"Allow",
68
+ "Resource"=>"*"}]}}}},
69
+ :groups=>
70
+ {"Admin"=>
71
+ {:path=>"/admin/",
72
+ :policies=>
73
+ {"Admin"=>
74
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}}},
75
+ "SES"=>
76
+ {:path=>"/ses/",
77
+ :policies=>
78
+ {"ses-policy"=>
79
+ {"Statement"=>
80
+ [{"Effect"=>"Allow",
81
+ "Action"=>"ses:SendRawEmail",
82
+ "Resource"=>"*"}]}}}}}
83
+ end
84
+
85
+ before(:each) do
86
+ apply { dsl }
87
+ end
88
+
89
+ context 'when rename user' do
90
+ let(:rename_user_dsl) do
91
+ <<-RUBY
92
+ user "bob2", :path=>"/devloper/", :renamed_from=>"bob" do
93
+ login_profile :password_reset_required=>true
94
+
95
+ groups(
96
+ "Admin",
97
+ "SES"
98
+ )
99
+
100
+ policy "S3" do
101
+ {"Statement"=>
102
+ [{"Action"=>
103
+ ["s3:Get*",
104
+ "s3:List*"],
105
+ "Effect"=>"Allow",
106
+ "Resource"=>"*"}]}
107
+ end
108
+ end
109
+
110
+ user "mary", :path=>"/staff/" do
111
+ policy "S3" do
112
+ {"Statement"=>
113
+ [{"Action"=>
114
+ ["s3:Get*",
115
+ "s3:List*"],
116
+ "Effect"=>"Allow",
117
+ "Resource"=>"*"}]}
118
+ end
119
+ end
120
+
121
+ group "Admin", :path=>"/admin/" do
122
+ policy "Admin" do
123
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
124
+ end
125
+ end
126
+
127
+ group "SES", :path=>"/ses/" do
128
+ policy "ses-policy" do
129
+ {"Statement"=>
130
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
131
+ end
132
+ end
133
+ RUBY
134
+ end
135
+
136
+ subject { client }
137
+
138
+ it do
139
+ updated = apply(subject) { rename_user_dsl }
140
+ expect(updated).to be_truthy
141
+ expected[:users]["bob2"] = expected[:users].delete("bob")
142
+ expect(export).to eq expected
143
+ end
144
+ end
145
+
146
+ context 'when rename group' do
147
+ let(:rename_group_dsl) do
148
+ <<-RUBY
149
+ user "bob", :path=>"/devloper/" do
150
+ login_profile :password_reset_required=>true
151
+
152
+ groups(
153
+ "Admin",
154
+ "SES2"
155
+ )
156
+
157
+ policy "S3" do
158
+ {"Statement"=>
159
+ [{"Action"=>
160
+ ["s3:Get*",
161
+ "s3:List*"],
162
+ "Effect"=>"Allow",
163
+ "Resource"=>"*"}]}
164
+ end
165
+ end
166
+
167
+ user "mary", :path=>"/staff/" do
168
+ policy "S3" do
169
+ {"Statement"=>
170
+ [{"Action"=>
171
+ ["s3:Get*",
172
+ "s3:List*"],
173
+ "Effect"=>"Allow",
174
+ "Resource"=>"*"}]}
175
+ end
176
+ end
177
+
178
+ group "Admin", :path=>"/admin/" do
179
+ policy "Admin" do
180
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
181
+ end
182
+ end
183
+
184
+ group "SES2", :path=>"/ses/", :renamed_from=>"SES2" do
185
+ policy "ses-policy" do
186
+ {"Statement"=>
187
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
188
+ end
189
+ end
190
+ RUBY
191
+ end
192
+
193
+ subject { client }
194
+
195
+ it do
196
+ updated = apply(subject) { rename_group_dsl }
197
+ expect(updated).to be_truthy
198
+ expected[:users]["bob"][:groups] = ["Admin", "SES2"]
199
+ expected[:groups]["SES2"] = expected[:groups].delete("SES")
200
+ expect(export).to eq expected
201
+ end
202
+ end
203
+
204
+ context 'when rename without renamed_from' do
205
+ let(:rename_without_renamed_from_dsl) do
206
+ <<-RUBY
207
+ user "bob2", :path=>"/devloper/" do
208
+ login_profile :password_reset_required=>true
209
+
210
+ groups(
211
+ "Admin",
212
+ "SES2"
213
+ )
214
+
215
+ policy "S3" do
216
+ {"Statement"=>
217
+ [{"Action"=>
218
+ ["s3:Get*",
219
+ "s3:List*"],
220
+ "Effect"=>"Allow",
221
+ "Resource"=>"*"}]}
222
+ end
223
+ end
224
+
225
+ user "mary", :path=>"/staff/" do
226
+ policy "S3" do
227
+ {"Statement"=>
228
+ [{"Action"=>
229
+ ["s3:Get*",
230
+ "s3:List*"],
231
+ "Effect"=>"Allow",
232
+ "Resource"=>"*"}]}
233
+ end
234
+ end
235
+
236
+ group "Admin", :path=>"/admin/" do
237
+ policy "Admin" do
238
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
239
+ end
240
+ end
241
+
242
+ group "SES2", :path=>"/ses/" do
243
+ policy "ses-policy" do
244
+ {"Statement"=>
245
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
246
+ end
247
+ end
248
+ RUBY
249
+ end
250
+
251
+ subject { client }
252
+
253
+ it do
254
+ updated = apply(subject) { rename_without_renamed_from_dsl }
255
+ expect(updated).to be_truthy
256
+ expected[:users]["bob"][:groups] = ["Admin", "SES2"]
257
+ expected[:users]["bob2"] = expected[:users].delete("bob")
258
+ expected[:groups]["SES2"] = expected[:groups].delete("SES")
259
+ expect(export).to eq expected
260
+ end
261
+ end
262
+ end
@@ -0,0 +1,434 @@
1
+ describe 'update' do
2
+ let(:dsl) do
3
+ <<-RUBY
4
+ user "bob", :path=>"/devloper/" do
5
+ login_profile :password_reset_required=>true
6
+
7
+ groups(
8
+ "Admin",
9
+ "SES"
10
+ )
11
+
12
+ policy "S3" do
13
+ {"Statement"=>
14
+ [{"Action"=>
15
+ ["s3:Get*",
16
+ "s3:List*"],
17
+ "Effect"=>"Allow",
18
+ "Resource"=>"*"}]}
19
+ end
20
+ end
21
+
22
+ user "mary", :path=>"/staff/" do
23
+ policy "S3" do
24
+ {"Statement"=>
25
+ [{"Action"=>
26
+ ["s3:Get*",
27
+ "s3:List*"],
28
+ "Effect"=>"Allow",
29
+ "Resource"=>"*"}]}
30
+ end
31
+ end
32
+
33
+ group "Admin", :path=>"/admin/" do
34
+ policy "Admin" do
35
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
36
+ end
37
+ end
38
+
39
+ group "SES", :path=>"/ses/" do
40
+ policy "ses-policy" do
41
+ {"Statement"=>
42
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
43
+ end
44
+ end
45
+ RUBY
46
+ end
47
+
48
+ let(:expected) do
49
+ {:users=>
50
+ {"bob"=>
51
+ {:path=>"/devloper/",
52
+ :groups=>["Admin", "SES"],
53
+ :policies=>
54
+ {"S3"=>
55
+ {"Statement"=>
56
+ [{"Action"=>["s3:Get*", "s3:List*"],
57
+ "Effect"=>"Allow",
58
+ "Resource"=>"*"}]}},
59
+ :login_profile=>{:password_reset_required=>true}},
60
+ "mary"=>
61
+ {:path=>"/staff/",
62
+ :groups=>[],
63
+ :policies=>
64
+ {"S3"=>
65
+ {"Statement"=>
66
+ [{"Action"=>["s3:Get*", "s3:List*"],
67
+ "Effect"=>"Allow",
68
+ "Resource"=>"*"}]}}}},
69
+ :groups=>
70
+ {"Admin"=>
71
+ {:path=>"/admin/",
72
+ :policies=>
73
+ {"Admin"=>
74
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}}},
75
+ "SES"=>
76
+ {:path=>"/ses/",
77
+ :policies=>
78
+ {"ses-policy"=>
79
+ {"Statement"=>
80
+ [{"Effect"=>"Allow",
81
+ "Action"=>"ses:SendRawEmail",
82
+ "Resource"=>"*"}]}}}}}
83
+ end
84
+
85
+ before(:each) do
86
+ apply { dsl }
87
+ end
88
+
89
+ context 'when no change' do
90
+ subject { client }
91
+
92
+ it do
93
+ updated = apply(subject) { dsl }
94
+ expect(updated).to be_falsey
95
+ expect(export).to eq expected
96
+ end
97
+ end
98
+
99
+ context 'when update policy' do
100
+ let(:update_policy_dsl) do
101
+ <<-RUBY
102
+ user "bob", :path=>"/devloper/" do
103
+ login_profile :password_reset_required=>true
104
+
105
+ groups(
106
+ "Admin",
107
+ "SES"
108
+ )
109
+
110
+ policy "S3" do
111
+ {"Statement"=>
112
+ [{"Action"=>
113
+ ["s3:Get*",
114
+ "s3:List*"],
115
+ "Effect"=>"Allow",
116
+ "Resource"=>"*"}]}
117
+ end
118
+ end
119
+
120
+ user "mary", :path=>"/staff/" do
121
+ policy "S3" do
122
+ {"Statement"=>
123
+ [{"Action"=>
124
+ ["s3:Get*",
125
+ "s3:Put*",
126
+ "s3:List*"],
127
+ "Effect"=>"Allow",
128
+ "Resource"=>"*"}]}
129
+ end
130
+ end
131
+
132
+ group "Admin", :path=>"/admin/" do
133
+ policy "Admin" do
134
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
135
+ end
136
+ end
137
+
138
+ group "SES", :path=>"/ses/" do
139
+ policy "ses-policy" do
140
+ {"Statement"=>
141
+ [{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
142
+ end
143
+ end
144
+ RUBY
145
+ end
146
+
147
+ subject { client }
148
+
149
+ it do
150
+ updated = apply(subject) { update_policy_dsl }
151
+ expect(updated).to be_truthy
152
+ expected[:users]["mary"][:policies]["S3"]["Statement"][0]["Action"] = ["s3:Get*", "s3:Put*", "s3:List*"]
153
+ expected[:groups]["SES"][:policies]["ses-policy"]["Statement"][0]["Action"] = "*"
154
+ expect(export).to eq expected
155
+ end
156
+ end
157
+
158
+ context 'when update path' do
159
+ let(:update_path_dsl) do
160
+ <<-RUBY
161
+ user "bob", :path=>"/devloper/" do
162
+ login_profile :password_reset_required=>true
163
+
164
+ groups(
165
+ "Admin",
166
+ "SES"
167
+ )
168
+
169
+ policy "S3" do
170
+ {"Statement"=>
171
+ [{"Action"=>
172
+ ["s3:Get*",
173
+ "s3:List*"],
174
+ "Effect"=>"Allow",
175
+ "Resource"=>"*"}]}
176
+ end
177
+ end
178
+
179
+ user "mary", :path=>"/xstaff/" do
180
+ policy "S3" do
181
+ {"Statement"=>
182
+ [{"Action"=>
183
+ ["s3:Get*",
184
+ "s3:List*"],
185
+ "Effect"=>"Allow",
186
+ "Resource"=>"*"}]}
187
+ end
188
+ end
189
+
190
+ group "Admin", :path=>"/admin/" do
191
+ policy "Admin" do
192
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
193
+ end
194
+ end
195
+
196
+ group "SES", :path=>"/ses/ses/" do
197
+ policy "ses-policy" do
198
+ {"Statement"=>
199
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
200
+ end
201
+ end
202
+ RUBY
203
+ end
204
+
205
+ subject { client }
206
+
207
+ it do
208
+ updated = apply(subject) { update_path_dsl }
209
+ expect(updated).to be_truthy
210
+ expected[:users]["mary"][:path] = "/xstaff/"
211
+ expected[:groups]["SES"][:path] = "/ses/ses/"
212
+ expect(export).to eq expected
213
+ end
214
+ end
215
+
216
+ context 'when update groups' do
217
+ let(:update_groups_dsl) do
218
+ <<-RUBY
219
+ user "bob", :path=>"/devloper/" do
220
+ login_profile :password_reset_required=>true
221
+
222
+ groups(
223
+ "Admin"
224
+ )
225
+
226
+ policy "S3" do
227
+ {"Statement"=>
228
+ [{"Action"=>
229
+ ["s3:Get*",
230
+ "s3:List*"],
231
+ "Effect"=>"Allow",
232
+ "Resource"=>"*"}]}
233
+ end
234
+ end
235
+
236
+ user "mary", :path=>"/staff/" do
237
+ groups(
238
+ "Admin",
239
+ "SES"
240
+ )
241
+
242
+ policy "S3" do
243
+ {"Statement"=>
244
+ [{"Action"=>
245
+ ["s3:Get*",
246
+ "s3:List*"],
247
+ "Effect"=>"Allow",
248
+ "Resource"=>"*"}]}
249
+ end
250
+ end
251
+
252
+ group "Admin", :path=>"/admin/" do
253
+ policy "Admin" do
254
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
255
+ end
256
+ end
257
+
258
+ group "SES", :path=>"/ses/" do
259
+ policy "ses-policy" do
260
+ {"Statement"=>
261
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
262
+ end
263
+ end
264
+ RUBY
265
+ end
266
+
267
+ subject { client }
268
+
269
+ it do
270
+ updated = apply(subject) { update_groups_dsl }
271
+ expect(updated).to be_truthy
272
+ expected[:users]["bob"][:groups] = ["Admin"]
273
+ expected[:users]["mary"][:groups] = ["Admin", "SES"]
274
+ expect(export).to eq expected
275
+ end
276
+ end
277
+
278
+ context 'when update login_profile' do
279
+ let(:update_login_profile_dsl) do
280
+ <<-RUBY
281
+ user "bob", :path=>"/devloper/" do
282
+ login_profile :password_reset_required=>false
283
+
284
+ groups(
285
+ "Admin",
286
+ "SES"
287
+ )
288
+
289
+ policy "S3" do
290
+ {"Statement"=>
291
+ [{"Action"=>
292
+ ["s3:Get*",
293
+ "s3:List*"],
294
+ "Effect"=>"Allow",
295
+ "Resource"=>"*"}]}
296
+ end
297
+ end
298
+
299
+ user "mary", :path=>"/staff/" do
300
+ policy "S3" do
301
+ {"Statement"=>
302
+ [{"Action"=>
303
+ ["s3:Get*",
304
+ "s3:List*"],
305
+ "Effect"=>"Allow",
306
+ "Resource"=>"*"}]}
307
+ end
308
+ end
309
+
310
+ group "Admin", :path=>"/admin/" do
311
+ policy "Admin" do
312
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
313
+ end
314
+ end
315
+
316
+ group "SES", :path=>"/ses/" do
317
+ policy "ses-policy" do
318
+ {"Statement"=>
319
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
320
+ end
321
+ end
322
+ RUBY
323
+ end
324
+
325
+ subject { client }
326
+
327
+ it do
328
+ updated = apply(subject) { update_login_profile_dsl }
329
+ expect(updated).to be_truthy
330
+ expected[:users]["bob"][:login_profile][:password_reset_required] = false
331
+ expect(export).to eq expected
332
+ end
333
+ end
334
+
335
+ context 'when delete login_profile' do
336
+ let(:delete_login_profile_dsl) do
337
+ <<-RUBY
338
+ user "bob", :path=>"/devloper/" do
339
+ groups(
340
+ "Admin",
341
+ "SES"
342
+ )
343
+
344
+ policy "S3" do
345
+ {"Statement"=>
346
+ [{"Action"=>
347
+ ["s3:Get*",
348
+ "s3:List*"],
349
+ "Effect"=>"Allow",
350
+ "Resource"=>"*"}]}
351
+ end
352
+ end
353
+
354
+ user "mary", :path=>"/staff/" do
355
+ policy "S3" do
356
+ {"Statement"=>
357
+ [{"Action"=>
358
+ ["s3:Get*",
359
+ "s3:List*"],
360
+ "Effect"=>"Allow",
361
+ "Resource"=>"*"}]}
362
+ end
363
+ end
364
+
365
+ group "Admin", :path=>"/admin/" do
366
+ policy "Admin" do
367
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
368
+ end
369
+ end
370
+
371
+ group "SES", :path=>"/ses/" do
372
+ policy "ses-policy" do
373
+ {"Statement"=>
374
+ [{"Effect"=>"Allow", "Action"=>"ses:SendRawEmail", "Resource"=>"*"}]}
375
+ end
376
+ end
377
+ RUBY
378
+ end
379
+
380
+ subject { client }
381
+
382
+ it do
383
+ updated = apply(subject) { delete_login_profile_dsl }
384
+ expect(updated).to be_truthy
385
+ expected[:users]["bob"].delete(:login_profile)
386
+ expect(export).to eq expected
387
+ end
388
+ end
389
+
390
+ context 'when delete policy' do
391
+ let(:delete_policy_dsl) do
392
+ <<-RUBY
393
+ user "bob", :path=>"/devloper/" do
394
+ login_profile :password_reset_required=>true
395
+
396
+ groups(
397
+ "Admin",
398
+ "SES"
399
+ )
400
+ end
401
+
402
+ user "mary", :path=>"/staff/" do
403
+ policy "S3" do
404
+ {"Statement"=>
405
+ [{"Action"=>
406
+ ["s3:Get*",
407
+ "s3:List*"],
408
+ "Effect"=>"Allow",
409
+ "Resource"=>"*"}]}
410
+ end
411
+ end
412
+
413
+ group "Admin", :path=>"/admin/" do
414
+ policy "Admin" do
415
+ {"Statement"=>[{"Effect"=>"Allow", "Action"=>"*", "Resource"=>"*"}]}
416
+ end
417
+ end
418
+
419
+ group "SES", :path=>"/ses/" do
420
+ end
421
+ RUBY
422
+ end
423
+
424
+ subject { client }
425
+
426
+ it do
427
+ updated = apply(subject) { delete_policy_dsl }
428
+ expect(updated).to be_truthy
429
+ expected[:users]["bob"][:policies].delete("S3")
430
+ expected[:groups]["SES"][:policies].delete("ses-policy")
431
+ expect(export).to eq expected
432
+ end
433
+ end
434
+ end
@@ -0,0 +1,84 @@
1
+ if ENV['TRAVIS']
2
+ require 'simplecov'
3
+ require 'coveralls'
4
+
5
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
6
+ SimpleCov.start do
7
+ add_filter "spec/"
8
+ end
9
+ end
10
+
11
+ require 'tempfile'
12
+ require 'miam'
13
+
14
+ Aws.config.update(
15
+ access_key_id: ENV['MIAM_TEST_ACCESS_KEY_ID'],
16
+ secret_access_key: ENV['MIAM_TEST_SECRET_ACCESS_KEY']
17
+ )
18
+
19
+ RSpec.configure do |config|
20
+ config.before(:each) do
21
+ apply { '' }
22
+ end
23
+
24
+ config.after(:all) do
25
+ apply { '' }
26
+ end
27
+ end
28
+
29
+ def client(user_options = {})
30
+ options = {
31
+ password_manager: Miam::PasswordManager.new('/dev/null'),
32
+ logger: Logger.new('/dev/null'),
33
+ no_progress: true
34
+ }
35
+
36
+ if_debug do
37
+ logger = Miam::Logger.instance
38
+ logger.set_debug(true)
39
+
40
+ options.update(
41
+ debug: true,
42
+ logger: logger,
43
+ aws_config: {
44
+ http_wire_trace: true,
45
+ logger: logger
46
+ }
47
+ )
48
+ end
49
+
50
+ options = options.merge(user_options)
51
+ Miam::Client.new(options)
52
+ end
53
+
54
+ def tempfile(content, options = {})
55
+ basename = "#{File.basename __FILE__}.#{$$}"
56
+ basename = [basename, options[:ext]] if options[:ext]
57
+
58
+ Tempfile.open(basename) do |f|
59
+ f.puts(content)
60
+ f.flush
61
+ f.rewind
62
+ yield(f)
63
+ end
64
+ end
65
+
66
+ def apply(cli = client)
67
+ tempfile(yield) do |f|
68
+ begin
69
+ cli.apply(f.path)
70
+ rescue Aws::IAM::Errors::EntityTemporarilyUnmodifiable
71
+ sleep 3
72
+ retry
73
+ end
74
+ end
75
+ end
76
+
77
+ def export(options = {})
78
+ cli = options.delete(:client) || Aws::IAM::Client.new
79
+ Miam::Exporter.export(cli, options)[0]
80
+ end
81
+
82
+ def if_debug
83
+ yield if ENV['DEBUG'] == '1'
84
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: miam
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Genki Sugawara
@@ -80,6 +80,48 @@ dependencies:
80
80
  - - ~>
81
81
  - !ruby/object:Gem::Version
82
82
  version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: 3.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-instafail
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: coveralls
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
83
125
  description: Miam is a tool to manage IAM. It defines the state of IAM using DSL,
84
126
  and updates IAM according to DSL.
85
127
  email:
@@ -90,6 +132,8 @@ extensions: []
90
132
  extra_rdoc_files: []
91
133
  files:
92
134
  - .gitignore
135
+ - .rspec
136
+ - .travis.yml
93
137
  - Gemfile
94
138
  - LICENSE.txt
95
139
  - README.md
@@ -110,6 +154,11 @@ files:
110
154
  - lib/miam/utils.rb
111
155
  - lib/miam/version.rb
112
156
  - miam.gemspec
157
+ - spec/miam/create_spec.rb
158
+ - spec/miam/delete_spec.rb
159
+ - spec/miam/rename_spec.rb
160
+ - spec/miam/update_spec.rb
161
+ - spec/spec_helper.rb
113
162
  homepage: https://github.com/winebarrel/miam
114
163
  licenses:
115
164
  - MIT
@@ -125,13 +174,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
125
174
  version: '0'
126
175
  required_rubygems_version: !ruby/object:Gem::Requirement
127
176
  requirements:
128
- - - '>'
177
+ - - '>='
129
178
  - !ruby/object:Gem::Version
130
- version: 1.3.1
179
+ version: '0'
131
180
  requirements: []
132
181
  rubyforge_project:
133
182
  rubygems_version: 2.4.1
134
183
  signing_key:
135
184
  specification_version: 4
136
185
  summary: Miam is a tool to manage IAM.
137
- test_files: []
186
+ test_files:
187
+ - spec/miam/create_spec.rb
188
+ - spec/miam/delete_spec.rb
189
+ - spec/miam/rename_spec.rb
190
+ - spec/miam/update_spec.rb
191
+ - spec/spec_helper.rb