aws-sdk-iam 1.0.0.rc1

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.
@@ -0,0 +1,191 @@
1
+ # WARNING ABOUT GENERATED CODE
2
+ #
3
+ # This file is generated. See the contributing for info on making contributions:
4
+ # https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
5
+ #
6
+ # WARNING ABOUT GENERATED CODE
7
+
8
+ module Aws
9
+ module IAM
10
+ class MfaDevice
11
+
12
+ extend Aws::Deprecations
13
+
14
+ # @overload def initialize(user_name, serial_number, options = {})
15
+ # @param [String] user_name
16
+ # @param [String] serial_number
17
+ # @option options [Client] :client
18
+ # @overload def initialize(options = {})
19
+ # @option options [required, String] :user_name
20
+ # @option options [required, String] :serial_number
21
+ # @option options [Client] :client
22
+ def initialize(*args)
23
+ options = Hash === args.last ? args.pop.dup : {}
24
+ @user_name = extract_user_name(args, options)
25
+ @serial_number = extract_serial_number(args, options)
26
+ @data = options.delete(:data)
27
+ @client = options.delete(:client) || Client.new(options)
28
+ end
29
+
30
+ # @!group Read-Only Attributes
31
+
32
+ # @return [String]
33
+ def user_name
34
+ @user_name
35
+ end
36
+
37
+ # @return [String]
38
+ def serial_number
39
+ @serial_number
40
+ end
41
+
42
+ # The date when the MFA device was enabled for the user.
43
+ # @return [Time]
44
+ def enable_date
45
+ data.enable_date
46
+ end
47
+
48
+ # @!endgroup
49
+
50
+ # @return [Client]
51
+ def client
52
+ @client
53
+ end
54
+
55
+ # @raise [Errors::ResourceNotLoadable]
56
+ # @api private
57
+ def load
58
+ msg = "#load is not implemented, data only available via enumeration"
59
+ raise Errors::ResourceNotLoadable, msg
60
+ end
61
+ alias :reload :load
62
+
63
+ # @raise [Errors::ResourceNotLoadableError] Raises when {#data_loaded?} is `false`.
64
+ # @return [Types::MFADevice]
65
+ # Returns the data for this {MfaDevice}.
66
+ def data
67
+ load unless @data
68
+ @data
69
+ end
70
+
71
+ # @return [Boolean]
72
+ # Returns `true` if this resource is loaded. Accessing attributes or
73
+ # {#data} on an unloaded resource will trigger a call to {#load}.
74
+ def data_loaded?
75
+ !!@data
76
+ end
77
+
78
+ # @!group Actions
79
+
80
+ # @example Request syntax with placeholder values
81
+ #
82
+ # mfa_device.associate({
83
+ # authentication_code_1: "authenticationCodeType", # required
84
+ # authentication_code_2: "authenticationCodeType", # required
85
+ # })
86
+ # @param [Hash] options ({})
87
+ # @option options [required, String] :authentication_code_1
88
+ # An authentication code emitted by the device.
89
+ #
90
+ # The format for this parameter is a string of 6 digits.
91
+ # @option options [required, String] :authentication_code_2
92
+ # A subsequent authentication code emitted by the device.
93
+ #
94
+ # The format for this parameter is a string of 6 digits.
95
+ # @return [EmptyStructure]
96
+ def associate(options = {})
97
+ options = options.merge(
98
+ user_name: @user_name,
99
+ serial_number: @serial_number
100
+ )
101
+ resp = @client.enable_mfa_device(options)
102
+ resp.data
103
+ end
104
+
105
+ # @example Request syntax with placeholder values
106
+ #
107
+ # mfa_device.disassociate()
108
+ # @param [Hash] options ({})
109
+ # @return [EmptyStructure]
110
+ def disassociate(options = {})
111
+ options = options.merge(
112
+ user_name: @user_name,
113
+ serial_number: @serial_number
114
+ )
115
+ resp = @client.deactivate_mfa_device(options)
116
+ resp.data
117
+ end
118
+
119
+ # @example Request syntax with placeholder values
120
+ #
121
+ # mfa_device.resync({
122
+ # authentication_code_1: "authenticationCodeType", # required
123
+ # authentication_code_2: "authenticationCodeType", # required
124
+ # })
125
+ # @param [Hash] options ({})
126
+ # @option options [required, String] :authentication_code_1
127
+ # An authentication code emitted by the device.
128
+ #
129
+ # The format for this parameter is a sequence of six digits.
130
+ # @option options [required, String] :authentication_code_2
131
+ # A subsequent authentication code emitted by the device.
132
+ #
133
+ # The format for this parameter is a sequence of six digits.
134
+ # @return [EmptyStructure]
135
+ def resync(options = {})
136
+ options = options.merge(
137
+ user_name: @user_name,
138
+ serial_number: @serial_number
139
+ )
140
+ resp = @client.resync_mfa_device(options)
141
+ resp.data
142
+ end
143
+
144
+ # @!group Associations
145
+
146
+ # @return [User]
147
+ def user
148
+ User.new(
149
+ name: @user_name,
150
+ client: @client
151
+ )
152
+ end
153
+
154
+ # @deprecated
155
+ # @api private
156
+ def identifiers
157
+ {
158
+ user_name: @user_name,
159
+ serial_number: @serial_number
160
+ }
161
+ end
162
+ deprecated(:identifiers)
163
+
164
+ private
165
+
166
+ def extract_user_name(args, options)
167
+ value = args[0] || options.delete(:user_name)
168
+ case value
169
+ when String then value
170
+ when nil then raise ArgumentError, "missing required option :user_name"
171
+ else
172
+ msg = "expected :user_name to be a String, got #{value.class}"
173
+ raise ArgumentError, msg
174
+ end
175
+ end
176
+
177
+ def extract_serial_number(args, options)
178
+ value = args[1] || options.delete(:serial_number)
179
+ case value
180
+ when String then value
181
+ when nil then raise ArgumentError, "missing required option :serial_number"
182
+ else
183
+ msg = "expected :serial_number to be a String, got #{value.class}"
184
+ raise ArgumentError, msg
185
+ end
186
+ end
187
+
188
+ class Collection < Aws::Resources::Collection; end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,554 @@
1
+ # WARNING ABOUT GENERATED CODE
2
+ #
3
+ # This file is generated. See the contributing for info on making contributions:
4
+ # https://github.com/aws/aws-sdk-ruby/blob/master/CONTRIBUTING.md
5
+ #
6
+ # WARNING ABOUT GENERATED CODE
7
+
8
+ module Aws
9
+ module IAM
10
+ class Policy
11
+
12
+ extend Aws::Deprecations
13
+
14
+ # @overload def initialize(arn, options = {})
15
+ # @param [String] arn
16
+ # @option options [Client] :client
17
+ # @overload def initialize(options = {})
18
+ # @option options [required, String] :arn
19
+ # @option options [Client] :client
20
+ def initialize(*args)
21
+ options = Hash === args.last ? args.pop.dup : {}
22
+ @arn = extract_arn(args, options)
23
+ @data = options.delete(:data)
24
+ @client = options.delete(:client) || Client.new(options)
25
+ end
26
+
27
+ # @!group Read-Only Attributes
28
+
29
+ # @return [String]
30
+ def arn
31
+ @arn
32
+ end
33
+
34
+ # The friendly name (not ARN) identifying the policy.
35
+ # @return [String]
36
+ def policy_name
37
+ data.policy_name
38
+ end
39
+
40
+ # The stable and unique string identifying the policy.
41
+ #
42
+ # For more information about IDs, see [IAM Identifiers][1] in the *Using
43
+ # IAM* guide.
44
+ #
45
+ #
46
+ #
47
+ # [1]: http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html
48
+ # @return [String]
49
+ def policy_id
50
+ data.policy_id
51
+ end
52
+
53
+ # The path to the policy.
54
+ #
55
+ # For more information about paths, see [IAM Identifiers][1] in the
56
+ # *Using IAM* guide.
57
+ #
58
+ #
59
+ #
60
+ # [1]: http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_Identifiers.html
61
+ # @return [String]
62
+ def path
63
+ data.path
64
+ end
65
+
66
+ # The identifier for the version of the policy that is set as the
67
+ # default version.
68
+ # @return [String]
69
+ def default_version_id
70
+ data.default_version_id
71
+ end
72
+
73
+ # The number of entities (users, groups, and roles) that the policy is
74
+ # attached to.
75
+ # @return [Integer]
76
+ def attachment_count
77
+ data.attachment_count
78
+ end
79
+
80
+ # Specifies whether the policy can be attached to an IAM user, group, or
81
+ # role.
82
+ # @return [Boolean]
83
+ def is_attachable
84
+ data.is_attachable
85
+ end
86
+
87
+ # A friendly description of the policy.
88
+ #
89
+ # This element is included in the response to the GetPolicy operation.
90
+ # It is not included in the response to the ListPolicies operation.
91
+ # @return [String]
92
+ def description
93
+ data.description
94
+ end
95
+
96
+ # The date and time, in [ISO 8601 date-time format][1], when the policy
97
+ # was created.
98
+ #
99
+ #
100
+ #
101
+ # [1]: http://www.iso.org/iso/iso8601
102
+ # @return [Time]
103
+ def create_date
104
+ data.create_date
105
+ end
106
+
107
+ # The date and time, in [ISO 8601 date-time format][1], when the policy
108
+ # was last updated.
109
+ #
110
+ # When a policy has only one version, this field contains the date and
111
+ # time when the policy was created. When a policy has more than one
112
+ # version, this field contains the date and time when the most recent
113
+ # policy version was created.
114
+ #
115
+ #
116
+ #
117
+ # [1]: http://www.iso.org/iso/iso8601
118
+ # @return [Time]
119
+ def update_date
120
+ data.update_date
121
+ end
122
+
123
+ # @!endgroup
124
+
125
+ # @return [Client]
126
+ def client
127
+ @client
128
+ end
129
+
130
+ # Loads, or reloads {#data} for the current {Policy}.
131
+ # Returns `self` making it possible to chain methods.
132
+ #
133
+ # policy.reload.data
134
+ #
135
+ # @return [self]
136
+ def load
137
+ resp = @client.get_policy(policy_arn: @arn)
138
+ @data = resp.policy
139
+ self
140
+ end
141
+ alias :reload :load
142
+
143
+ # @return [Types::Policy]
144
+ # Returns the data for this {Policy}. Calls
145
+ # {Client#get_policy} if {#data_loaded?} is `false`.
146
+ def data
147
+ load unless @data
148
+ @data
149
+ end
150
+
151
+ # @return [Boolean]
152
+ # Returns `true` if this resource is loaded. Accessing attributes or
153
+ # {#data} on an unloaded resource will trigger a call to {#load}.
154
+ def data_loaded?
155
+ !!@data
156
+ end
157
+
158
+ # @!group Actions
159
+
160
+ # @example Request syntax with placeholder values
161
+ #
162
+ # policy.attach_group({
163
+ # group_name: "groupNameType", # required
164
+ # })
165
+ # @param [Hash] options ({})
166
+ # @option options [required, String] :group_name
167
+ # The name (friendly name, not ARN) of the group to attach the policy
168
+ # to.
169
+ #
170
+ # The [regex pattern][1] for this parameter is a string of characters
171
+ # consisting of upper and lowercase alphanumeric characters with no
172
+ # spaces. You can also include any of the following characters: =,.@-
173
+ #
174
+ #
175
+ #
176
+ # [1]: http://wikipedia.org/wiki/regex
177
+ # @return [EmptyStructure]
178
+ def attach_group(options = {})
179
+ options = options.merge(policy_arn: @arn)
180
+ resp = @client.attach_group_policy(options)
181
+ resp.data
182
+ end
183
+
184
+ # @example Request syntax with placeholder values
185
+ #
186
+ # policy.attach_role({
187
+ # role_name: "roleNameType", # required
188
+ # })
189
+ # @param [Hash] options ({})
190
+ # @option options [required, String] :role_name
191
+ # The name (friendly name, not ARN) of the role to attach the policy to.
192
+ #
193
+ # The [regex pattern][1] for this parameter is a string of characters
194
+ # consisting of upper and lowercase alphanumeric characters with no
195
+ # spaces. You can also include any of the following characters: =,.@-
196
+ #
197
+ #
198
+ #
199
+ # [1]: http://wikipedia.org/wiki/regex
200
+ # @return [EmptyStructure]
201
+ def attach_role(options = {})
202
+ options = options.merge(policy_arn: @arn)
203
+ resp = @client.attach_role_policy(options)
204
+ resp.data
205
+ end
206
+
207
+ # @example Request syntax with placeholder values
208
+ #
209
+ # policy.attach_user({
210
+ # user_name: "userNameType", # required
211
+ # })
212
+ # @param [Hash] options ({})
213
+ # @option options [required, String] :user_name
214
+ # The name (friendly name, not ARN) of the IAM user to attach the policy
215
+ # to.
216
+ #
217
+ # The [regex pattern][1] for this parameter is a string of characters
218
+ # consisting of upper and lowercase alphanumeric characters with no
219
+ # spaces. You can also include any of the following characters: =,.@-
220
+ #
221
+ #
222
+ #
223
+ # [1]: http://wikipedia.org/wiki/regex
224
+ # @return [EmptyStructure]
225
+ def attach_user(options = {})
226
+ options = options.merge(policy_arn: @arn)
227
+ resp = @client.attach_user_policy(options)
228
+ resp.data
229
+ end
230
+
231
+ # @example Request syntax with placeholder values
232
+ #
233
+ # policyversion = policy.create_version({
234
+ # policy_document: "policyDocumentType", # required
235
+ # set_as_default: false,
236
+ # })
237
+ # @param [Hash] options ({})
238
+ # @option options [required, String] :policy_document
239
+ # The JSON policy document that you want to use as the content for this
240
+ # new version of the policy.
241
+ #
242
+ # The [regex pattern][1] for this parameter is a string of characters
243
+ # consisting of any printable ASCII character ranging from the space
244
+ # character (\\u0020) through end of the ASCII character range
245
+ # (\\u00FF). It also includes the special characters tab (\\u0009), line
246
+ # feed (\\u000A), and carriage return (\\u000D).
247
+ #
248
+ #
249
+ #
250
+ # [1]: http://wikipedia.org/wiki/regex
251
+ # @option options [Boolean] :set_as_default
252
+ # Specifies whether to set this version as the policy's default
253
+ # version.
254
+ #
255
+ # When this parameter is `true`, the new policy version becomes the
256
+ # operative version; that is, the version that is in effect for the IAM
257
+ # users, groups, and roles that the policy is attached to.
258
+ #
259
+ # For more information about managed policy versions, see [Versioning
260
+ # for Managed Policies][1] in the *IAM User Guide*.
261
+ #
262
+ #
263
+ #
264
+ # [1]: http://docs.aws.amazon.com/IAM/latest/UserGuide/policies-managed-versions.html
265
+ # @return [PolicyVersion]
266
+ def create_version(options = {})
267
+ options = options.merge(policy_arn: @arn)
268
+ resp = @client.create_policy_version(options)
269
+ PolicyVersion.new(
270
+ arn: @arn,
271
+ version_id: resp.data.policy_version.version_id,
272
+ client: @client
273
+ )
274
+ end
275
+
276
+ # @example Request syntax with placeholder values
277
+ #
278
+ # policy.delete()
279
+ # @param [Hash] options ({})
280
+ # @return [EmptyStructure]
281
+ def delete(options = {})
282
+ options = options.merge(policy_arn: @arn)
283
+ resp = @client.delete_policy(options)
284
+ resp.data
285
+ end
286
+
287
+ # @example Request syntax with placeholder values
288
+ #
289
+ # policy.detach_group({
290
+ # group_name: "groupNameType", # required
291
+ # })
292
+ # @param [Hash] options ({})
293
+ # @option options [required, String] :group_name
294
+ # The name (friendly name, not ARN) of the IAM group to detach the
295
+ # policy from.
296
+ #
297
+ # The [regex pattern][1] for this parameter is a string of characters
298
+ # consisting of upper and lowercase alphanumeric characters with no
299
+ # spaces. You can also include any of the following characters: =,.@-
300
+ #
301
+ #
302
+ #
303
+ # [1]: http://wikipedia.org/wiki/regex
304
+ # @return [EmptyStructure]
305
+ def detach_group(options = {})
306
+ options = options.merge(policy_arn: @arn)
307
+ resp = @client.detach_group_policy(options)
308
+ resp.data
309
+ end
310
+
311
+ # @example Request syntax with placeholder values
312
+ #
313
+ # policy.detach_role({
314
+ # role_name: "roleNameType", # required
315
+ # })
316
+ # @param [Hash] options ({})
317
+ # @option options [required, String] :role_name
318
+ # The name (friendly name, not ARN) of the IAM role to detach the policy
319
+ # from.
320
+ #
321
+ # The [regex pattern][1] for this parameter is a string of characters
322
+ # consisting of upper and lowercase alphanumeric characters with no
323
+ # spaces. You can also include any of the following characters: =,.@-
324
+ #
325
+ #
326
+ #
327
+ # [1]: http://wikipedia.org/wiki/regex
328
+ # @return [EmptyStructure]
329
+ def detach_role(options = {})
330
+ options = options.merge(policy_arn: @arn)
331
+ resp = @client.detach_role_policy(options)
332
+ resp.data
333
+ end
334
+
335
+ # @example Request syntax with placeholder values
336
+ #
337
+ # policy.detach_user({
338
+ # user_name: "userNameType", # required
339
+ # })
340
+ # @param [Hash] options ({})
341
+ # @option options [required, String] :user_name
342
+ # The name (friendly name, not ARN) of the IAM user to detach the policy
343
+ # from.
344
+ #
345
+ # The [regex pattern][1] for this parameter is a string of characters
346
+ # consisting of upper and lowercase alphanumeric characters with no
347
+ # spaces. You can also include any of the following characters: =,.@-
348
+ #
349
+ #
350
+ #
351
+ # [1]: http://wikipedia.org/wiki/regex
352
+ # @return [EmptyStructure]
353
+ def detach_user(options = {})
354
+ options = options.merge(policy_arn: @arn)
355
+ resp = @client.detach_user_policy(options)
356
+ resp.data
357
+ end
358
+
359
+ # @!group Associations
360
+
361
+ # @example Request syntax with placeholder values
362
+ #
363
+ # attachedgroups = policy.attached_groups({
364
+ # path_prefix: "pathType",
365
+ # })
366
+ # @param [Hash] options ({})
367
+ # @option options [String] :path_prefix
368
+ # The path prefix for filtering the results. This parameter is optional.
369
+ # If it is not included, it defaults to a slash (/), listing all
370
+ # entities.
371
+ #
372
+ # The [regex pattern][1] for this parameter is a string of characters
373
+ # consisting of either a forward slash (/) by itself or a string that
374
+ # must begin and end with forward slashes, containing any ASCII
375
+ # character from the ! (\\u0021) thru the DEL character (\\u007F),
376
+ # including most punctuation characters, digits, and upper and
377
+ # lowercased letters.
378
+ #
379
+ #
380
+ #
381
+ # [1]: http://wikipedia.org/wiki/regex
382
+ # @return [Group::Collection]
383
+ def attached_groups(options = {})
384
+ batches = Enumerator.new do |y|
385
+ options = options.merge(
386
+ policy_arn: @arn,
387
+ entity_filter: "Group"
388
+ )
389
+ resp = @client.list_entities_for_policy(options)
390
+ resp.each_page do |page|
391
+ batch = []
392
+ page.data.policy_groups.each do |p|
393
+ batch << Group.new(
394
+ name: p.group_name,
395
+ data: p,
396
+ client: @client
397
+ )
398
+ end
399
+ y.yield(batch)
400
+ end
401
+ end
402
+ Group::Collection.new(batches)
403
+ end
404
+
405
+ # @example Request syntax with placeholder values
406
+ #
407
+ # attachedroles = policy.attached_roles({
408
+ # path_prefix: "pathType",
409
+ # })
410
+ # @param [Hash] options ({})
411
+ # @option options [String] :path_prefix
412
+ # The path prefix for filtering the results. This parameter is optional.
413
+ # If it is not included, it defaults to a slash (/), listing all
414
+ # entities.
415
+ #
416
+ # The [regex pattern][1] for this parameter is a string of characters
417
+ # consisting of either a forward slash (/) by itself or a string that
418
+ # must begin and end with forward slashes, containing any ASCII
419
+ # character from the ! (\\u0021) thru the DEL character (\\u007F),
420
+ # including most punctuation characters, digits, and upper and
421
+ # lowercased letters.
422
+ #
423
+ #
424
+ #
425
+ # [1]: http://wikipedia.org/wiki/regex
426
+ # @return [Role::Collection]
427
+ def attached_roles(options = {})
428
+ batches = Enumerator.new do |y|
429
+ options = options.merge(
430
+ policy_arn: @arn,
431
+ entity_filter: "Role"
432
+ )
433
+ resp = @client.list_entities_for_policy(options)
434
+ resp.each_page do |page|
435
+ batch = []
436
+ page.data.policy_roles.each do |p|
437
+ batch << Role.new(
438
+ name: p.role_name,
439
+ data: p,
440
+ client: @client
441
+ )
442
+ end
443
+ y.yield(batch)
444
+ end
445
+ end
446
+ Role::Collection.new(batches)
447
+ end
448
+
449
+ # @example Request syntax with placeholder values
450
+ #
451
+ # attachedusers = policy.attached_users({
452
+ # path_prefix: "pathType",
453
+ # })
454
+ # @param [Hash] options ({})
455
+ # @option options [String] :path_prefix
456
+ # The path prefix for filtering the results. This parameter is optional.
457
+ # If it is not included, it defaults to a slash (/), listing all
458
+ # entities.
459
+ #
460
+ # The [regex pattern][1] for this parameter is a string of characters
461
+ # consisting of either a forward slash (/) by itself or a string that
462
+ # must begin and end with forward slashes, containing any ASCII
463
+ # character from the ! (\\u0021) thru the DEL character (\\u007F),
464
+ # including most punctuation characters, digits, and upper and
465
+ # lowercased letters.
466
+ #
467
+ #
468
+ #
469
+ # [1]: http://wikipedia.org/wiki/regex
470
+ # @return [User::Collection]
471
+ def attached_users(options = {})
472
+ batches = Enumerator.new do |y|
473
+ options = options.merge(
474
+ policy_arn: @arn,
475
+ entity_filter: "User"
476
+ )
477
+ resp = @client.list_entities_for_policy(options)
478
+ resp.each_page do |page|
479
+ batch = []
480
+ page.data.policy_users.each do |p|
481
+ batch << User.new(
482
+ name: p.user_name,
483
+ data: p,
484
+ client: @client
485
+ )
486
+ end
487
+ y.yield(batch)
488
+ end
489
+ end
490
+ User::Collection.new(batches)
491
+ end
492
+
493
+ # @return [PolicyVersion, nil]
494
+ def default_version
495
+ if data.default_version_id
496
+ PolicyVersion.new(
497
+ arn: @arn,
498
+ version_id: data.default_version_id,
499
+ client: @client
500
+ )
501
+ else
502
+ nil
503
+ end
504
+ end
505
+
506
+ # @example Request syntax with placeholder values
507
+ #
508
+ # versions = policy.versions()
509
+ # @param [Hash] options ({})
510
+ # @return [PolicyVersion::Collection]
511
+ def versions(options = {})
512
+ batches = Enumerator.new do |y|
513
+ options = options.merge(policy_arn: @arn)
514
+ resp = @client.list_policy_versions(options)
515
+ resp.each_page do |page|
516
+ batch = []
517
+ page.data.versions.each do |v|
518
+ batch << PolicyVersion.new(
519
+ arn: @arn,
520
+ version_id: v.version_id,
521
+ data: v,
522
+ client: @client
523
+ )
524
+ end
525
+ y.yield(batch)
526
+ end
527
+ end
528
+ PolicyVersion::Collection.new(batches)
529
+ end
530
+
531
+ # @deprecated
532
+ # @api private
533
+ def identifiers
534
+ { arn: @arn }
535
+ end
536
+ deprecated(:identifiers)
537
+
538
+ private
539
+
540
+ def extract_arn(args, options)
541
+ value = args[0] || options.delete(:arn)
542
+ case value
543
+ when String then value
544
+ when nil then raise ArgumentError, "missing required option :arn"
545
+ else
546
+ msg = "expected :arn to be a String, got #{value.class}"
547
+ raise ArgumentError, msg
548
+ end
549
+ end
550
+
551
+ class Collection < Aws::Resources::Collection; end
552
+ end
553
+ end
554
+ end