aws-sdk-lakeformation 1.26.0 → 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a5baf612c864eedf2679448691dbd96b221097a8133badce1375c76dc0f48297
4
- data.tar.gz: 160f22b141638242a1ec24a16ab1847c7f891814d562171ce74d2aeb5ce79e9e
3
+ metadata.gz: 67be00f9d8e93dc5f7c706448f9a6e796983d4e46d8ef7a3cb290443c519860e
4
+ data.tar.gz: 36f80e3dabfca28c2e94b626e7bab35a2637ef09c16347f48211f89853ab923f
5
5
  SHA512:
6
- metadata.gz: a68dd4966f4aa25e5425431b5c08de671d2416b97598d4fffa268be176b84e518bc76be181642d2ad42b20d767b9ba8b9ca63e98a61f636bd8069c8b7437e4d8
7
- data.tar.gz: a3ffcafde2bce08b60fb311d71b07fb1125da7cdddf6396b95e23b98d86d2f87976c2e09ed66ac4ae9acb25e277eddd1ca5cd86aba99dd33787fffa31d61b8aa
6
+ metadata.gz: 1ecd40c538304cd7bcd1f27da07ce4437705997e613ea1570f872797d1f9f2a7dfe8fa6412c06af1253f35d41327a758d0ffb5691f48e5269c488f2aa0020060
7
+ data.tar.gz: f5a46e83cac035e2b949c4d8b6f4ac1d7dad42607aec579b37d71da5dbb51c013b5e5ee245a00a56d77373c96f324ebdd7ae254dfe32aedd772b00dd7e6b3ed4
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 1.28.0 (2022-10-25)
5
+ ------------------
6
+
7
+ * Feature - Code Generated Changes, see `./build_tools` or `aws-sdk-core`'s CHANGELOG.md for details.
8
+
9
+ 1.27.0 (2022-08-17)
10
+ ------------------
11
+
12
+ * Feature - This release adds a new API support "AssumeDecoratedRoleWithSAML" and also release updates the corresponding documentation.
13
+
4
14
  1.26.0 (2022-03-22)
5
15
  ------------------
6
16
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.26.0
1
+ 1.28.0
@@ -30,7 +30,7 @@ require 'aws-sdk-core/plugins/http_checksum.rb'
30
30
  require 'aws-sdk-core/plugins/checksum_algorithm.rb'
31
31
  require 'aws-sdk-core/plugins/defaults_mode.rb'
32
32
  require 'aws-sdk-core/plugins/recursion_detection.rb'
33
- require 'aws-sdk-core/plugins/signature_v4.rb'
33
+ require 'aws-sdk-core/plugins/sign.rb'
34
34
  require 'aws-sdk-core/plugins/protocols/rest_json.rb'
35
35
 
36
36
  Aws::Plugins::GlobalConfiguration.add_identifier(:lakeformation)
@@ -79,8 +79,9 @@ module Aws::LakeFormation
79
79
  add_plugin(Aws::Plugins::ChecksumAlgorithm)
80
80
  add_plugin(Aws::Plugins::DefaultsMode)
81
81
  add_plugin(Aws::Plugins::RecursionDetection)
82
- add_plugin(Aws::Plugins::SignatureV4)
82
+ add_plugin(Aws::Plugins::Sign)
83
83
  add_plugin(Aws::Plugins::Protocols::RestJson)
84
+ add_plugin(Aws::LakeFormation::Plugins::Endpoints)
84
85
 
85
86
  # @overload initialize(options)
86
87
  # @param [Hash] options
@@ -287,6 +288,19 @@ module Aws::LakeFormation
287
288
  # ** Please note ** When response stubbing is enabled, no HTTP
288
289
  # requests are made, and retries are disabled.
289
290
  #
291
+ # @option options [Aws::TokenProvider] :token_provider
292
+ # A Bearer Token Provider. This can be an instance of any one of the
293
+ # following classes:
294
+ #
295
+ # * `Aws::StaticTokenProvider` - Used for configuring static, non-refreshing
296
+ # tokens.
297
+ #
298
+ # * `Aws::SSOTokenProvider` - Used for loading tokens from AWS SSO using an
299
+ # access token generated from `aws login`.
300
+ #
301
+ # When `:token_provider` is not configured directly, the `Aws::TokenProviderChain`
302
+ # will be used to search for tokens configured for your profile in shared configuration files.
303
+ #
290
304
  # @option options [Boolean] :use_dualstack_endpoint
291
305
  # When set to `true`, dualstack enabled endpoints (with `.aws` TLD)
292
306
  # will be used if available.
@@ -300,6 +314,9 @@ module Aws::LakeFormation
300
314
  # When `true`, request parameters are validated before
301
315
  # sending the request.
302
316
  #
317
+ # @option options [Aws::LakeFormation::EndpointProvider] :endpoint_provider
318
+ # The endpoint provider used to resolve endpoints. Any object that responds to `#resolve_endpoint(parameters)` where `parameters` is a Struct similar to `Aws::LakeFormation::EndpointParameters`
319
+ #
303
320
  # @option options [URI::HTTP,String] :http_proxy A proxy to send
304
321
  # requests through. Formatted like 'http://proxy.com:123'.
305
322
  #
@@ -450,6 +467,73 @@ module Aws::LakeFormation
450
467
  req.send_request(options)
451
468
  end
452
469
 
470
+ # Allows a caller to assume an IAM role decorated as the SAML user
471
+ # specified in the SAML assertion included in the request. This
472
+ # decoration allows Lake Formation to enforce access policies against
473
+ # the SAML users and groups. This API operation requires SAML federation
474
+ # setup in the caller’s account as it can only be called with valid SAML
475
+ # assertions. Lake Formation does not scope down the permission of the
476
+ # assumed role. All permissions attached to the role via the SAML
477
+ # federation setup will be included in the role session.
478
+ #
479
+ # This decorated role is expected to access data in Amazon S3 by getting
480
+ # temporary access from Lake Formation which is authorized via the
481
+ # virtual API `GetDataAccess`. Therefore, all SAML roles that can be
482
+ # assumed via `AssumeDecoratedRoleWithSAML` must at a minimum include
483
+ # `lakeformation:GetDataAccess` in their role policies. A typical IAM
484
+ # policy attached to such a role would look as follows:
485
+ #
486
+ # @option params [required, String] :saml_assertion
487
+ # A SAML assertion consisting of an assertion statement for the user who
488
+ # needs temporary credentials. This must match the SAML assertion that
489
+ # was issued to IAM. This must be Base64 encoded.
490
+ #
491
+ # @option params [required, String] :role_arn
492
+ # The role that represents an IAM principal whose scope down policy
493
+ # allows it to call credential vending APIs such as
494
+ # `GetTemporaryTableCredentials`. The caller must also have iam:PassRole
495
+ # permission on this role.
496
+ #
497
+ # @option params [required, String] :principal_arn
498
+ # The Amazon Resource Name (ARN) of the SAML provider in IAM that
499
+ # describes the IdP.
500
+ #
501
+ # @option params [Integer] :duration_seconds
502
+ # The time period, between 900 and 43,200 seconds, for the timeout of
503
+ # the temporary credentials.
504
+ #
505
+ # @return [Types::AssumeDecoratedRoleWithSAMLResponse] Returns a {Seahorse::Client::Response response} object which responds to the following methods:
506
+ #
507
+ # * {Types::AssumeDecoratedRoleWithSAMLResponse#access_key_id #access_key_id} => String
508
+ # * {Types::AssumeDecoratedRoleWithSAMLResponse#secret_access_key #secret_access_key} => String
509
+ # * {Types::AssumeDecoratedRoleWithSAMLResponse#session_token #session_token} => String
510
+ # * {Types::AssumeDecoratedRoleWithSAMLResponse#expiration #expiration} => Time
511
+ #
512
+ # @example Request syntax with placeholder values
513
+ #
514
+ # resp = client.assume_decorated_role_with_saml({
515
+ # saml_assertion: "SAMLAssertionString", # required
516
+ # role_arn: "IAMRoleArn", # required
517
+ # principal_arn: "IAMSAMLProviderArn", # required
518
+ # duration_seconds: 1,
519
+ # })
520
+ #
521
+ # @example Response structure
522
+ #
523
+ # resp.access_key_id #=> String
524
+ # resp.secret_access_key #=> String
525
+ # resp.session_token #=> String
526
+ # resp.expiration #=> Time
527
+ #
528
+ # @see http://docs.aws.amazon.com/goto/WebAPI/lakeformation-2017-03-31/AssumeDecoratedRoleWithSAML AWS API Documentation
529
+ #
530
+ # @overload assume_decorated_role_with_saml(params = {})
531
+ # @param [Hash] params ({})
532
+ def assume_decorated_role_with_saml(params = {}, options = {})
533
+ req = build_request(:assume_decorated_role_with_saml, params)
534
+ req.send_request(options)
535
+ end
536
+
453
537
  # Batch operation to grant permissions to the principal.
454
538
  #
455
539
  # @option params [String] :catalog_id
@@ -868,13 +952,12 @@ module Aws::LakeFormation
868
952
  req.send_request(options)
869
953
  end
870
954
 
871
- # Deletes the specified LF-tag key name. If the attribute key does not
872
- # exist or the LF-tag does not exist, then the operation will not do
873
- # anything. If the attribute key exists, then the operation checks if
874
- # any resources are tagged with this attribute key, if yes, the API
875
- # throws a 400 Exception with the message "Delete not allowed" as the
876
- # LF-tag key is still attached with resources. You can consider
877
- # untagging resources with this LF-tag key.
955
+ # Deletes the specified LF-tag given a key name. If the input parameter
956
+ # tag key was not found, then the operation will throw an exception.
957
+ # When you delete an LF-tag, the `LFTagPolicy` attached to the LF-tag
958
+ # becomes invalid. If the deleted LF-tag was still assigned to any
959
+ # resource, the tag policy attach to the deleted LF-tag will no longer
960
+ # be applied to the resource.
878
961
  #
879
962
  # @option params [String] :catalog_id
880
963
  # The identifier for the Data Catalog. By default, the account ID. The
@@ -3018,7 +3101,7 @@ module Aws::LakeFormation
3018
3101
  params: params,
3019
3102
  config: config)
3020
3103
  context[:gem_name] = 'aws-sdk-lakeformation'
3021
- context[:gem_version] = '1.26.0'
3104
+ context[:gem_version] = '1.28.0'
3022
3105
  Seahorse::Client::Request.new(handlers, context)
3023
3106
  end
3024
3107
 
@@ -20,6 +20,8 @@ module Aws::LakeFormation
20
20
  AddObjectInput = Shapes::StructureShape.new(name: 'AddObjectInput')
21
21
  AllRowsWildcard = Shapes::StructureShape.new(name: 'AllRowsWildcard')
22
22
  AlreadyExistsException = Shapes::StructureShape.new(name: 'AlreadyExistsException')
23
+ AssumeDecoratedRoleWithSAMLRequest = Shapes::StructureShape.new(name: 'AssumeDecoratedRoleWithSAMLRequest')
24
+ AssumeDecoratedRoleWithSAMLResponse = Shapes::StructureShape.new(name: 'AssumeDecoratedRoleWithSAMLResponse')
23
25
  AuditContext = Shapes::StructureShape.new(name: 'AuditContext')
24
26
  AuditContextString = Shapes::StringShape.new(name: 'AuditContextString')
25
27
  AuthorizedSessionTagValueList = Shapes::ListShape.new(name: 'AuthorizedSessionTagValueList')
@@ -120,6 +122,7 @@ module Aws::LakeFormation
120
122
  GrantPermissionsRequest = Shapes::StructureShape.new(name: 'GrantPermissionsRequest')
121
123
  GrantPermissionsResponse = Shapes::StructureShape.new(name: 'GrantPermissionsResponse')
122
124
  IAMRoleArn = Shapes::StringShape.new(name: 'IAMRoleArn')
125
+ IAMSAMLProviderArn = Shapes::StringShape.new(name: 'IAMSAMLProviderArn')
123
126
  Identifier = Shapes::StringShape.new(name: 'Identifier')
124
127
  Integer = Shapes::IntegerShape.new(name: 'Integer')
125
128
  InternalServiceException = Shapes::StructureShape.new(name: 'InternalServiceException')
@@ -198,6 +201,7 @@ module Aws::LakeFormation
198
201
  RevokePermissionsRequest = Shapes::StructureShape.new(name: 'RevokePermissionsRequest')
199
202
  RevokePermissionsResponse = Shapes::StructureShape.new(name: 'RevokePermissionsResponse')
200
203
  RowFilter = Shapes::StructureShape.new(name: 'RowFilter')
204
+ SAMLAssertionString = Shapes::StringShape.new(name: 'SAMLAssertionString')
201
205
  SearchDatabasesByLFTagsRequest = Shapes::StructureShape.new(name: 'SearchDatabasesByLFTagsRequest')
202
206
  SearchDatabasesByLFTagsResponse = Shapes::StructureShape.new(name: 'SearchDatabasesByLFTagsResponse')
203
207
  SearchTablesByLFTagsRequest = Shapes::StructureShape.new(name: 'SearchTablesByLFTagsRequest')
@@ -287,6 +291,18 @@ module Aws::LakeFormation
287
291
  AlreadyExistsException.add_member(:message, Shapes::ShapeRef.new(shape: MessageString, location_name: "Message"))
288
292
  AlreadyExistsException.struct_class = Types::AlreadyExistsException
289
293
 
294
+ AssumeDecoratedRoleWithSAMLRequest.add_member(:saml_assertion, Shapes::ShapeRef.new(shape: SAMLAssertionString, required: true, location_name: "SAMLAssertion"))
295
+ AssumeDecoratedRoleWithSAMLRequest.add_member(:role_arn, Shapes::ShapeRef.new(shape: IAMRoleArn, required: true, location_name: "RoleArn"))
296
+ AssumeDecoratedRoleWithSAMLRequest.add_member(:principal_arn, Shapes::ShapeRef.new(shape: IAMSAMLProviderArn, required: true, location_name: "PrincipalArn"))
297
+ AssumeDecoratedRoleWithSAMLRequest.add_member(:duration_seconds, Shapes::ShapeRef.new(shape: CredentialTimeoutDurationSecondInteger, location_name: "DurationSeconds"))
298
+ AssumeDecoratedRoleWithSAMLRequest.struct_class = Types::AssumeDecoratedRoleWithSAMLRequest
299
+
300
+ AssumeDecoratedRoleWithSAMLResponse.add_member(:access_key_id, Shapes::ShapeRef.new(shape: AccessKeyIdString, location_name: "AccessKeyId"))
301
+ AssumeDecoratedRoleWithSAMLResponse.add_member(:secret_access_key, Shapes::ShapeRef.new(shape: SecretAccessKeyString, location_name: "SecretAccessKey"))
302
+ AssumeDecoratedRoleWithSAMLResponse.add_member(:session_token, Shapes::ShapeRef.new(shape: SessionTokenString, location_name: "SessionToken"))
303
+ AssumeDecoratedRoleWithSAMLResponse.add_member(:expiration, Shapes::ShapeRef.new(shape: ExpirationTimestamp, location_name: "Expiration"))
304
+ AssumeDecoratedRoleWithSAMLResponse.struct_class = Types::AssumeDecoratedRoleWithSAMLResponse
305
+
290
306
  AuditContext.add_member(:additional_audit_context, Shapes::ShapeRef.new(shape: AuditContextString, location_name: "AdditionalAuditContext"))
291
307
  AuditContext.struct_class = Types::AuditContext
292
308
 
@@ -1007,6 +1023,19 @@ module Aws::LakeFormation
1007
1023
  o.errors << Shapes::ShapeRef.new(shape: ConcurrentModificationException)
1008
1024
  end)
1009
1025
 
1026
+ api.add_operation(:assume_decorated_role_with_saml, Seahorse::Model::Operation.new.tap do |o|
1027
+ o.name = "AssumeDecoratedRoleWithSAML"
1028
+ o.http_method = "POST"
1029
+ o.http_request_uri = "/AssumeDecoratedRoleWithSAML"
1030
+ o.input = Shapes::ShapeRef.new(shape: AssumeDecoratedRoleWithSAMLRequest)
1031
+ o.output = Shapes::ShapeRef.new(shape: AssumeDecoratedRoleWithSAMLResponse)
1032
+ o.errors << Shapes::ShapeRef.new(shape: InvalidInputException)
1033
+ o.errors << Shapes::ShapeRef.new(shape: InternalServiceException)
1034
+ o.errors << Shapes::ShapeRef.new(shape: OperationTimeoutException)
1035
+ o.errors << Shapes::ShapeRef.new(shape: EntityNotFoundException)
1036
+ o.errors << Shapes::ShapeRef.new(shape: AccessDeniedException)
1037
+ end)
1038
+
1010
1039
  api.add_operation(:batch_grant_permissions, Seahorse::Model::Operation.new.tap do |o|
1011
1040
  o.name = "BatchGrantPermissions"
1012
1041
  o.http_method = "POST"
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WARNING ABOUT GENERATED CODE
4
+ #
5
+ # This file is generated. See the contributing guide for more information:
6
+ # https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
7
+ #
8
+ # WARNING ABOUT GENERATED CODE
9
+
10
+ module Aws::LakeFormation
11
+ # Endpoint parameters used to influence endpoints per request.
12
+ #
13
+ # @!attribute region
14
+ # The AWS region used to dispatch the request.
15
+ #
16
+ # @return [String]
17
+ #
18
+ # @!attribute use_dual_stack
19
+ # When true, use the dual-stack endpoint. If the configured endpoint does not support dual-stack, dispatching the request MAY return an error.
20
+ #
21
+ # @return [Boolean]
22
+ #
23
+ # @!attribute use_fips
24
+ # When true, send this request to the FIPS-compliant regional endpoint. If the configured endpoint does not have a FIPS compliant endpoint, dispatching the request will return an error.
25
+ #
26
+ # @return [Boolean]
27
+ #
28
+ # @!attribute endpoint
29
+ # Override the endpoint used to send this request
30
+ #
31
+ # @return [String]
32
+ #
33
+ EndpointParameters = Struct.new(
34
+ :region,
35
+ :use_dual_stack,
36
+ :use_fips,
37
+ :endpoint,
38
+ ) do
39
+ include Aws::Structure
40
+
41
+ # @api private
42
+ class << self
43
+ PARAM_MAP = {
44
+ 'Region' => :region,
45
+ 'UseDualStack' => :use_dual_stack,
46
+ 'UseFIPS' => :use_fips,
47
+ 'Endpoint' => :endpoint,
48
+ }.freeze
49
+ end
50
+
51
+ def initialize(options = {})
52
+ self[:region] = options[:region]
53
+ self[:use_dual_stack] = options[:use_dual_stack]
54
+ self[:use_dual_stack] = false if self[:use_dual_stack].nil?
55
+ if self[:use_dual_stack].nil?
56
+ raise ArgumentError, "Missing required EndpointParameter: :use_dual_stack"
57
+ end
58
+ self[:use_fips] = options[:use_fips]
59
+ self[:use_fips] = false if self[:use_fips].nil?
60
+ if self[:use_fips].nil?
61
+ raise ArgumentError, "Missing required EndpointParameter: :use_fips"
62
+ end
63
+ self[:endpoint] = options[:endpoint]
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ # WARNING ABOUT GENERATED CODE
4
+ #
5
+ # This file is generated. See the contributing guide for more information:
6
+ # https://github.com/aws/aws-sdk-ruby/blob/version-3/CONTRIBUTING.md
7
+ #
8
+ # WARNING ABOUT GENERATED CODE
9
+
10
+ module Aws::LakeFormation
11
+ class EndpointProvider
12
+ def initialize(rule_set = nil)
13
+ @@rule_set ||= begin
14
+ endpoint_rules = Aws::Json.load(Base64.decode64(RULES))
15
+ Aws::Endpoints::RuleSet.new(
16
+ version: endpoint_rules['version'],
17
+ service_id: endpoint_rules['serviceId'],
18
+ parameters: endpoint_rules['parameters'],
19
+ rules: endpoint_rules['rules']
20
+ )
21
+ end
22
+ @provider = Aws::Endpoints::RulesProvider.new(rule_set || @@rule_set)
23
+ end
24
+
25
+ def resolve_endpoint(parameters)
26
+ @provider.resolve_endpoint(parameters)
27
+ end
28
+
29
+ # @api private
30
+ RULES = <<-JSON
31
+ eyJ2ZXJzaW9uIjoiMS4wIiwicGFyYW1ldGVycyI6eyJSZWdpb24iOnsiYnVp
32
+ bHRJbiI6IkFXUzo6UmVnaW9uIiwicmVxdWlyZWQiOmZhbHNlLCJkb2N1bWVu
33
+ dGF0aW9uIjoiVGhlIEFXUyByZWdpb24gdXNlZCB0byBkaXNwYXRjaCB0aGUg
34
+ cmVxdWVzdC4iLCJ0eXBlIjoiU3RyaW5nIn0sIlVzZUR1YWxTdGFjayI6eyJi
35
+ dWlsdEluIjoiQVdTOjpVc2VEdWFsU3RhY2siLCJyZXF1aXJlZCI6dHJ1ZSwi
36
+ ZGVmYXVsdCI6ZmFsc2UsImRvY3VtZW50YXRpb24iOiJXaGVuIHRydWUsIHVz
37
+ ZSB0aGUgZHVhbC1zdGFjayBlbmRwb2ludC4gSWYgdGhlIGNvbmZpZ3VyZWQg
38
+ ZW5kcG9pbnQgZG9lcyBub3Qgc3VwcG9ydCBkdWFsLXN0YWNrLCBkaXNwYXRj
39
+ aGluZyB0aGUgcmVxdWVzdCBNQVkgcmV0dXJuIGFuIGVycm9yLiIsInR5cGUi
40
+ OiJCb29sZWFuIn0sIlVzZUZJUFMiOnsiYnVpbHRJbiI6IkFXUzo6VXNlRklQ
41
+ UyIsInJlcXVpcmVkIjp0cnVlLCJkZWZhdWx0IjpmYWxzZSwiZG9jdW1lbnRh
42
+ dGlvbiI6IldoZW4gdHJ1ZSwgc2VuZCB0aGlzIHJlcXVlc3QgdG8gdGhlIEZJ
43
+ UFMtY29tcGxpYW50IHJlZ2lvbmFsIGVuZHBvaW50LiBJZiB0aGUgY29uZmln
44
+ dXJlZCBlbmRwb2ludCBkb2VzIG5vdCBoYXZlIGEgRklQUyBjb21wbGlhbnQg
45
+ ZW5kcG9pbnQsIGRpc3BhdGNoaW5nIHRoZSByZXF1ZXN0IHdpbGwgcmV0dXJu
46
+ IGFuIGVycm9yLiIsInR5cGUiOiJCb29sZWFuIn0sIkVuZHBvaW50Ijp7ImJ1
47
+ aWx0SW4iOiJTREs6OkVuZHBvaW50IiwicmVxdWlyZWQiOmZhbHNlLCJkb2N1
48
+ bWVudGF0aW9uIjoiT3ZlcnJpZGUgdGhlIGVuZHBvaW50IHVzZWQgdG8gc2Vu
49
+ ZCB0aGlzIHJlcXVlc3QiLCJ0eXBlIjoiU3RyaW5nIn19LCJydWxlcyI6W3si
50
+ Y29uZGl0aW9ucyI6W3siZm4iOiJhd3MucGFydGl0aW9uIiwiYXJndiI6W3si
51
+ cmVmIjoiUmVnaW9uIn1dLCJhc3NpZ24iOiJQYXJ0aXRpb25SZXN1bHQifV0s
52
+ InR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRpdGlvbnMiOlt7ImZuIjoi
53
+ aXNTZXQiLCJhcmd2IjpbeyJyZWYiOiJFbmRwb2ludCJ9XX0seyJmbiI6InBh
54
+ cnNlVVJMIiwiYXJndiI6W3sicmVmIjoiRW5kcG9pbnQifV0sImFzc2lnbiI6
55
+ InVybCJ9XSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3siY29uZGl0aW9ucyI6
56
+ W3siZm4iOiJib29sZWFuRXF1YWxzIiwiYXJndiI6W3sicmVmIjoiVXNlRklQ
57
+ UyJ9LHRydWVdfV0sImVycm9yIjoiSW52YWxpZCBDb25maWd1cmF0aW9uOiBG
58
+ SVBTIGFuZCBjdXN0b20gZW5kcG9pbnQgYXJlIG5vdCBzdXBwb3J0ZWQiLCJ0
59
+ eXBlIjoiZXJyb3IifSx7ImNvbmRpdGlvbnMiOltdLCJ0eXBlIjoidHJlZSIs
60
+ InJ1bGVzIjpbeyJjb25kaXRpb25zIjpbeyJmbiI6ImJvb2xlYW5FcXVhbHMi
61
+ LCJhcmd2IjpbeyJyZWYiOiJVc2VEdWFsU3RhY2sifSx0cnVlXX1dLCJlcnJv
62
+ ciI6IkludmFsaWQgQ29uZmlndXJhdGlvbjogRHVhbHN0YWNrIGFuZCBjdXN0
63
+ b20gZW5kcG9pbnQgYXJlIG5vdCBzdXBwb3J0ZWQiLCJ0eXBlIjoiZXJyb3Ii
64
+ fSx7ImNvbmRpdGlvbnMiOltdLCJlbmRwb2ludCI6eyJ1cmwiOnsicmVmIjoi
65
+ RW5kcG9pbnQifSwicHJvcGVydGllcyI6e30sImhlYWRlcnMiOnt9fSwidHlw
66
+ ZSI6ImVuZHBvaW50In1dfV19LHsiY29uZGl0aW9ucyI6W3siZm4iOiJib29s
67
+ ZWFuRXF1YWxzIiwiYXJndiI6W3sicmVmIjoiVXNlRklQUyJ9LHRydWVdfSx7
68
+ ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt7InJlZiI6IlVzZUR1YWxT
69
+ dGFjayJ9LHRydWVdfV0sInR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRp
70
+ dGlvbnMiOlt7ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt0cnVlLHsi
71
+ Zm4iOiJnZXRBdHRyIiwiYXJndiI6W3sicmVmIjoiUGFydGl0aW9uUmVzdWx0
72
+ In0sInN1cHBvcnRzRklQUyJdfV19LHsiZm4iOiJib29sZWFuRXF1YWxzIiwi
73
+ YXJndiI6W3RydWUseyJmbiI6ImdldEF0dHIiLCJhcmd2IjpbeyJyZWYiOiJQ
74
+ YXJ0aXRpb25SZXN1bHQifSwic3VwcG9ydHNEdWFsU3RhY2siXX1dfV0sInR5
75
+ cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRpdGlvbnMiOltdLCJlbmRwb2lu
76
+ dCI6eyJ1cmwiOiJodHRwczovL2xha2Vmb3JtYXRpb24tZmlwcy57UmVnaW9u
77
+ fS57UGFydGl0aW9uUmVzdWx0I2R1YWxTdGFja0Ruc1N1ZmZpeH0iLCJwcm9w
78
+ ZXJ0aWVzIjp7fSwiaGVhZGVycyI6e319LCJ0eXBlIjoiZW5kcG9pbnQifV19
79
+ LHsiY29uZGl0aW9ucyI6W10sImVycm9yIjoiRklQUyBhbmQgRHVhbFN0YWNr
80
+ IGFyZSBlbmFibGVkLCBidXQgdGhpcyBwYXJ0aXRpb24gZG9lcyBub3Qgc3Vw
81
+ cG9ydCBvbmUgb3IgYm90aCIsInR5cGUiOiJlcnJvciJ9XX0seyJjb25kaXRp
82
+ b25zIjpbeyJmbiI6ImJvb2xlYW5FcXVhbHMiLCJhcmd2IjpbeyJyZWYiOiJV
83
+ c2VGSVBTIn0sdHJ1ZV19XSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3siY29u
84
+ ZGl0aW9ucyI6W3siZm4iOiJib29sZWFuRXF1YWxzIiwiYXJndiI6W3RydWUs
85
+ eyJmbiI6ImdldEF0dHIiLCJhcmd2IjpbeyJyZWYiOiJQYXJ0aXRpb25SZXN1
86
+ bHQifSwic3VwcG9ydHNGSVBTIl19XX1dLCJ0eXBlIjoidHJlZSIsInJ1bGVz
87
+ IjpbeyJjb25kaXRpb25zIjpbXSwidHlwZSI6InRyZWUiLCJydWxlcyI6W3si
88
+ Y29uZGl0aW9ucyI6W10sImVuZHBvaW50Ijp7InVybCI6Imh0dHBzOi8vbGFr
89
+ ZWZvcm1hdGlvbi1maXBzLntSZWdpb259LntQYXJ0aXRpb25SZXN1bHQjZG5z
90
+ U3VmZml4fSIsInByb3BlcnRpZXMiOnt9LCJoZWFkZXJzIjp7fX0sInR5cGUi
91
+ OiJlbmRwb2ludCJ9XX1dfSx7ImNvbmRpdGlvbnMiOltdLCJlcnJvciI6IkZJ
92
+ UFMgaXMgZW5hYmxlZCBidXQgdGhpcyBwYXJ0aXRpb24gZG9lcyBub3Qgc3Vw
93
+ cG9ydCBGSVBTIiwidHlwZSI6ImVycm9yIn1dfSx7ImNvbmRpdGlvbnMiOlt7
94
+ ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt7InJlZiI6IlVzZUR1YWxT
95
+ dGFjayJ9LHRydWVdfV0sInR5cGUiOiJ0cmVlIiwicnVsZXMiOlt7ImNvbmRp
96
+ dGlvbnMiOlt7ImZuIjoiYm9vbGVhbkVxdWFscyIsImFyZ3YiOlt0cnVlLHsi
97
+ Zm4iOiJnZXRBdHRyIiwiYXJndiI6W3sicmVmIjoiUGFydGl0aW9uUmVzdWx0
98
+ In0sInN1cHBvcnRzRHVhbFN0YWNrIl19XX1dLCJ0eXBlIjoidHJlZSIsInJ1
99
+ bGVzIjpbeyJjb25kaXRpb25zIjpbXSwiZW5kcG9pbnQiOnsidXJsIjoiaHR0
100
+ cHM6Ly9sYWtlZm9ybWF0aW9uLntSZWdpb259LntQYXJ0aXRpb25SZXN1bHQj
101
+ ZHVhbFN0YWNrRG5zU3VmZml4fSIsInByb3BlcnRpZXMiOnt9LCJoZWFkZXJz
102
+ Ijp7fX0sInR5cGUiOiJlbmRwb2ludCJ9XX0seyJjb25kaXRpb25zIjpbXSwi
103
+ ZXJyb3IiOiJEdWFsU3RhY2sgaXMgZW5hYmxlZCBidXQgdGhpcyBwYXJ0aXRp
104
+ b24gZG9lcyBub3Qgc3VwcG9ydCBEdWFsU3RhY2siLCJ0eXBlIjoiZXJyb3Ii
105
+ fV19LHsiY29uZGl0aW9ucyI6W10sImVuZHBvaW50Ijp7InVybCI6Imh0dHBz
106
+ Oi8vbGFrZWZvcm1hdGlvbi57UmVnaW9ufS57UGFydGl0aW9uUmVzdWx0I2Ru
107
+ c1N1ZmZpeH0iLCJwcm9wZXJ0aWVzIjp7fSwiaGVhZGVycyI6e319LCJ0eXBl
108
+ IjoiZW5kcG9pbnQifV19XX0=
109
+
110
+ JSON
111
+ end
112
+ end