aws-sdk-core 3.160.0 → 3.166.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -2
  3. data/VERSION +1 -1
  4. data/lib/aws-sdk-core/arn.rb +13 -0
  5. data/lib/aws-sdk-core/binary/encode_handler.rb +12 -1
  6. data/lib/aws-sdk-core/endpoints/condition.rb +36 -0
  7. data/lib/aws-sdk-core/endpoints/endpoint.rb +17 -0
  8. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +71 -0
  9. data/lib/aws-sdk-core/endpoints/error_rule.rb +37 -0
  10. data/lib/aws-sdk-core/endpoints/function.rb +75 -0
  11. data/lib/aws-sdk-core/endpoints/matchers.rb +127 -0
  12. data/lib/aws-sdk-core/endpoints/reference.rb +26 -0
  13. data/lib/aws-sdk-core/endpoints/rule.rb +20 -0
  14. data/lib/aws-sdk-core/endpoints/rule_set.rb +47 -0
  15. data/lib/aws-sdk-core/endpoints/rules_provider.rb +32 -0
  16. data/lib/aws-sdk-core/endpoints/templater.rb +52 -0
  17. data/lib/aws-sdk-core/endpoints/tree_rule.rb +40 -0
  18. data/lib/aws-sdk-core/endpoints/url.rb +59 -0
  19. data/lib/aws-sdk-core/endpoints.rb +74 -0
  20. data/lib/aws-sdk-core/json/error_handler.rb +10 -1
  21. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +24 -0
  22. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +6 -2
  23. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +5 -0
  24. data/lib/aws-sdk-core/plugins/sign.rb +190 -0
  25. data/lib/aws-sdk-core/plugins/signature_v2.rb +1 -0
  26. data/lib/aws-sdk-core/plugins/signature_v4.rb +1 -0
  27. data/lib/aws-sdk-core/rest/request/headers.rb +2 -6
  28. data/lib/aws-sdk-core.rb +4 -0
  29. data/lib/aws-sdk-sso/client.rb +20 -3
  30. data/lib/aws-sdk-sso/endpoint_parameters.rb +66 -0
  31. data/lib/aws-sdk-sso/endpoint_provider.rb +112 -0
  32. data/lib/aws-sdk-sso/endpoints.rb +71 -0
  33. data/lib/aws-sdk-sso/plugins/endpoints.rb +76 -0
  34. data/lib/aws-sdk-sso.rb +5 -1
  35. data/lib/aws-sdk-ssooidc/client.rb +20 -3
  36. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +66 -0
  37. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +111 -0
  38. data/lib/aws-sdk-ssooidc/endpoints.rb +57 -0
  39. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +74 -0
  40. data/lib/aws-sdk-ssooidc.rb +5 -1
  41. data/lib/aws-sdk-sts/client.rb +20 -3
  42. data/lib/aws-sdk-sts/endpoint_parameters.rb +78 -0
  43. data/lib/aws-sdk-sts/endpoint_provider.rb +229 -0
  44. data/lib/aws-sdk-sts/endpoints.rb +135 -0
  45. data/lib/aws-sdk-sts/plugins/endpoints.rb +84 -0
  46. data/lib/aws-sdk-sts/presigner.rb +13 -15
  47. data/lib/aws-sdk-sts.rb +5 -1
  48. data/lib/seahorse/client/async_base.rb +0 -1
  49. data/lib/seahorse/client/configuration.rb +2 -2
  50. data/lib/seahorse/util.rb +4 -0
  51. metadata +33 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f34212034338f257652b55b099b6685cfbea0e44646c3ef8339be579297fb418
4
- data.tar.gz: 582f8d577a8d2b2c271ab8144489b7322219671bbca2448eb69b21f18c19dd5e
3
+ metadata.gz: a81b60918988fd7ee9366d79ced7e41bae6f7f2e55cffe4a0e5eb1cc1cd9c9c3
4
+ data.tar.gz: 5facaa68ef59e079763525a392996dfdce6495e0c187a5b001df78be71648abb
5
5
  SHA512:
6
- metadata.gz: 987250246fffa11d7f54844a3d63378ea54c4686b8c414c1d4d47840375c0381f42469647139df124efcf5c022a8ba61302c0c580128e005e6469ce35dcca879
7
- data.tar.gz: f1a8337d8af92abb9a1b35011d058b3e5beabed32960cdd8d46e28a63cccb786ae1c8c7937262fb3b39654c0295e7603e4303e47708dcf5512c59a123555567c
6
+ metadata.gz: b3ee6e89b330461fd71923488bbc657a4f359d2e082e7ea9d5300279234843ce20a59b2a22620f282e252dc89c8d9c3b18fcfe7206898fe8f8ed6af2ce5fff81
7
+ data.tar.gz: 5ffab77f4bf826684b99ffda8dd6877be3382bcfe70816147f25fb1d13349c14c66b923dd45bf5510e81c569ce46f0f3967f478a061df802332c5b3f2a5059e9
data/CHANGELOG.md CHANGED
@@ -1,6 +1,49 @@
1
1
  Unreleased Changes
2
2
  ------------------
3
3
 
4
+ 3.166.0 (2022-10-26)
5
+ ------------------
6
+
7
+ * Feature - Updated Aws::STS::Client with the latest API changes.
8
+
9
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
10
+
11
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
12
+
13
+ 3.165.1 (2022-10-25)
14
+ ------------------
15
+
16
+ * Issue - Require the SignatureV4 plugin to fix compatability with older `aws-sdk-s3` versions (#2774).
17
+
18
+ 3.165.0 (2022-10-25)
19
+ ------------------
20
+
21
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
22
+
23
+ * Feature - Updated Aws::SSO::Client with the latest API changes.
24
+
25
+ * Feature - Add support for service gems to dynamically determine their own endpoints via modeling. Service gems now generate a plugin called "Endpoints" that defines configuration for EndpointProvider, a new public type, and any client config related to endpoints. Endpoint providers will resolve values using another new public type, Endpoint Parameters, generated for each service. The plugin will use the endpoint provider to resolve an endpoint and then apply it to the request prior to serialization. Endpoint providers can be composed to change endpoint resolution logic, i.e. for testing. In addition to endpoints, the endpoint provider may also override the authentication scheme (auth scheme) which details how the request should be signed for the endpoint. A new "Sign" plugin in core replaces the SignatureV4 plugin that will generically sign any type of auth scheme that a service might have.
26
+
27
+ 3.164.0 (2022-10-21)
28
+ ------------------
29
+
30
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
31
+
32
+ 3.163.0 (2022-10-20)
33
+ ------------------
34
+
35
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
36
+
37
+ 3.162.0 (2022-10-19)
38
+ ------------------
39
+
40
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
41
+
42
+ 3.161.0 (2022-10-18)
43
+ ------------------
44
+
45
+ * Feature - Support AwsQueryCompatible trait to read error code from x-amzn-query-error header.
46
+
4
47
  3.160.0 (2022-10-13)
5
48
  ------------------
6
49
 
@@ -14,7 +57,7 @@ Unreleased Changes
14
57
  3.158.1 (2022-10-06)
15
58
  ------------------
16
59
 
17
- * Issue - Ensure that the ReadCallbackIO is always unwrapped (#2761).
60
+ * Issue - Ensure that the ReadCallbackIO is always unwrapped (#2761).
18
61
 
19
62
  3.158.0 (2022-09-30)
20
63
  ------------------
@@ -133,6 +176,8 @@ Unreleased Changes
133
176
 
134
177
  * Feature - Updated Aws::SSO::Client with the latest API changes.
135
178
 
179
+ * Feature - Updated Aws::SSOOIDC::Client with the latest API changes.
180
+
136
181
  3.135.0 (2022-08-24)
137
182
  ------------------
138
183
 
@@ -144,12 +189,13 @@ Unreleased Changes
144
189
  * Feature - Updated Aws::SSO::Client with the latest API changes.
145
190
 
146
191
  * Feature - Add support for Bearer Token Authentication and TokenProviders.
192
+
147
193
  * Issue - Validate that `_X_AMZN_TRACE_ID` ENV value contains only valid, non-control characters.
148
194
 
149
195
  3.133.0 (2022-08-22)
150
196
  ------------------
151
197
 
152
- * Feature - Moved functionality from `aws-sdk-ssoidc` into core.
198
+ * Feature - Moved functionality from `aws-sdk-ssooidc` into core.
153
199
 
154
200
  3.132.0 (2022-08-08)
155
201
  ------------------
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.160.0
1
+ 3.166.0
@@ -88,5 +88,18 @@ module Aws
88
88
  resource: @resource
89
89
  }
90
90
  end
91
+
92
+ # Return the ARN as JSON
93
+ #
94
+ # @return [Hash]
95
+ def as_json(_options = nil)
96
+ {
97
+ 'partition' => @partition,
98
+ 'service' => @service,
99
+ 'region' => @region,
100
+ 'accountId' => @account_id,
101
+ 'resource' => @resource
102
+ }
103
+ end
91
104
  end
92
105
  end
@@ -13,7 +13,7 @@ module Aws
13
13
  context.config.api.metadata['protocol'],
14
14
  eventstream_member,
15
15
  context.operation.input,
16
- context.config.sigv4_signer
16
+ signer_for(context)
17
17
  )
18
18
  context[:input_event_emitter] = input_es_handler.event_emitter
19
19
  end
@@ -22,6 +22,17 @@ module Aws
22
22
 
23
23
  private
24
24
 
25
+ def signer_for(context)
26
+ # New endpoint/signing logic, use the auth scheme to make a signer
27
+ if context[:auth_scheme]
28
+ Aws::Plugins::Sign.signer_for(context[:auth_scheme], context.config)
29
+ else
30
+ # Previous implementation always assumed sigv4_signer from config.
31
+ # Relies only on sigv4 signing (and plugin) for event stream services
32
+ context.config.sigv4_signer
33
+ end
34
+ end
35
+
25
36
  def eventstream_input?(ctx)
26
37
  ctx.operation.input.shape.members.each do |_, ref|
27
38
  return ref if ref.eventstream
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class Condition
7
+ def initialize(fn:, argv:, assign: nil)
8
+ @fn = Function.new(fn: fn, argv: argv)
9
+ @assign = assign
10
+ @assigned = {}
11
+ end
12
+
13
+ attr_reader :fn
14
+ attr_reader :argv
15
+ attr_reader :assign
16
+
17
+ attr_reader :assigned
18
+
19
+ def match?(parameters, assigns)
20
+ output = @fn.call(parameters, assigns)
21
+ @assigned = @assigned.merge({ @assign => output }) if @assign
22
+ output
23
+ end
24
+
25
+ def self.from_json(conditions_json)
26
+ conditions_json.each.with_object([]) do |condition, conditions|
27
+ conditions << new(
28
+ fn: condition['fn'],
29
+ argv: condition['argv'],
30
+ assign: condition['assign']
31
+ )
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ class Endpoint
6
+ def initialize(url:, properties: {}, headers: {})
7
+ @url = url
8
+ @properties = properties
9
+ @headers = headers
10
+ end
11
+
12
+ attr_reader :url
13
+ attr_reader :properties
14
+ attr_reader :headers
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class EndpointRule < Rule
7
+ def initialize(type: 'endpoint', conditions:, endpoint:,
8
+ documentation: nil)
9
+ @type = type
10
+ @conditions = Condition.from_json(conditions)
11
+ @endpoint = endpoint
12
+ @documentation = documentation
13
+ end
14
+
15
+ attr_reader :type
16
+ attr_reader :conditions
17
+ attr_reader :endpoint
18
+ attr_reader :documentation
19
+
20
+ def match(parameters, assigned = {})
21
+ assigns = assigned.dup
22
+ matched = conditions.all? do |condition|
23
+ output = condition.match?(parameters, assigns)
24
+ assigns = assigns.merge(condition.assigned) if condition.assign
25
+ output
26
+ end
27
+ resolved_endpoint(parameters, assigns) if matched
28
+ end
29
+
30
+ def resolved_endpoint(parameters, assigns)
31
+ Endpoint.new(
32
+ url: resolve_value(@endpoint['url'], parameters, assigns),
33
+ properties: resolve_properties(
34
+ @endpoint['properties'] || {},
35
+ parameters,
36
+ assigns
37
+ ),
38
+ headers: resolve_headers(parameters, assigns)
39
+ )
40
+ end
41
+
42
+ private
43
+
44
+ def resolve_headers(parameters, assigns)
45
+ (@endpoint['headers'] || {}).each.with_object({}) do |(key, arr), headers|
46
+ headers[key] = []
47
+ arr.each do |value|
48
+ headers[key] << resolve_value(value, parameters, assigns)
49
+ end
50
+ end
51
+ end
52
+
53
+ def resolve_properties(obj, parameters, assigns)
54
+ case obj
55
+ when Hash
56
+ obj.each.with_object({}) do |(key, value), hash|
57
+ hash[key] = resolve_properties(value, parameters, assigns)
58
+ end
59
+ when Array
60
+ obj.collect { |value| resolve_properties(value, parameters, assigns) }
61
+ else
62
+ if obj.is_a?(String)
63
+ Templater.resolve(obj, parameters, assigns)
64
+ else
65
+ obj
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class ErrorRule < Rule
7
+ def initialize(type: 'error', conditions:, error: nil, documentation: nil)
8
+ @type = type
9
+ @conditions = Condition.from_json(conditions)
10
+ @error = error
11
+ @documentation = documentation
12
+ end
13
+
14
+ attr_reader :type
15
+ attr_reader :conditions
16
+ attr_reader :error
17
+ attr_reader :documentation
18
+
19
+ def match(parameters, assigned = {})
20
+ assigns = assigned.dup
21
+ matched = conditions.all? do |condition|
22
+ output = condition.match?(parameters, assigns)
23
+ assigns = assigns.merge(condition.assigned) if condition.assign
24
+ output
25
+ end
26
+ resolved_error(parameters, assigns) if matched
27
+ end
28
+
29
+ private
30
+
31
+ def resolved_error(parameters, assigns)
32
+ error = resolve_value(@error, parameters, assigns)
33
+ ArgumentError.new(error)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class Function
7
+ def initialize(fn:, argv:)
8
+ @fn = fn
9
+ @argv = build_argv(argv)
10
+ end
11
+
12
+ attr_reader :fn
13
+ attr_reader :argv
14
+
15
+ def call(parameters, assigns)
16
+ args = []
17
+ @argv.each do |arg|
18
+ if arg.is_a?(Reference)
19
+ args << arg.resolve(parameters, assigns)
20
+ elsif arg.is_a?(Function)
21
+ args << arg.call(parameters, assigns)
22
+ else
23
+ if arg.is_a?(String)
24
+ arg = Templater.resolve(arg, parameters, assigns)
25
+ end
26
+ args << arg
27
+ end
28
+ end
29
+
30
+ case @fn
31
+ when 'isSet'
32
+ Matchers.set?(*args)
33
+ when 'not'
34
+ Matchers.not(*args)
35
+ when 'getAttr'
36
+ Matchers.attr(*args)
37
+ when 'substring'
38
+ Matchers.substring(*args)
39
+ when 'stringEquals'
40
+ Matchers.string_equals?(*args)
41
+ when 'booleanEquals'
42
+ Matchers.boolean_equals?(*args)
43
+ when 'uriEncode'
44
+ Matchers.uri_encode(*args)
45
+ when 'parseURL'
46
+ Matchers.parse_url(*args)
47
+ when 'isValidHostLabel'
48
+ Matchers.valid_host_label?(*args)
49
+ when 'aws.partition'
50
+ Matchers.aws_partition(*args)
51
+ when 'aws.parseArn'
52
+ Matchers.aws_parse_arn(*args)
53
+ when 'aws.isVirtualHostableS3Bucket'
54
+ Matchers.aws_virtual_hostable_s3_bucket?(*args)
55
+ else
56
+ raise "Function not found: #{@fn}"
57
+ end
58
+ end
59
+
60
+ private
61
+
62
+ def build_argv(argv_json)
63
+ argv_json.each.with_object([]) do |arg, argv|
64
+ argv << if arg.is_a?(Hash) && arg['ref']
65
+ Reference.new(ref: arg['ref'])
66
+ elsif arg.is_a?(Hash) && arg['fn']
67
+ Function.new(fn: arg['fn'], argv: arg['argv'])
68
+ else
69
+ arg
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,127 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cgi'
4
+
5
+ module Aws
6
+ module Endpoints
7
+ # generic matcher functions for service endpoints
8
+ # @api private
9
+ module Matchers
10
+ # Regex that extracts anything in square brackets
11
+ BRACKET_REGEX = /\[(.*?)\]/.freeze
12
+
13
+ # CORE
14
+
15
+ # isSet(value: Option<T>) bool
16
+ def self.set?(value)
17
+ !value.nil?
18
+ end
19
+
20
+ # not(value: bool) bool
21
+ def self.not(bool)
22
+ !bool
23
+ end
24
+
25
+ # getAttr(value: Object | Array, path: string) Document
26
+ def self.attr(value, path)
27
+ parts = path.split('.')
28
+
29
+ val = if (index = parts.first[BRACKET_REGEX, 1])
30
+ # remove brackets and index from part before indexing
31
+ value[parts.first.gsub(BRACKET_REGEX, '')][index.to_i]
32
+ else
33
+ value[parts.first]
34
+ end
35
+
36
+ if parts.size == 1
37
+ val
38
+ else
39
+ attr(val, parts.slice(1..-1).join('.'))
40
+ end
41
+ end
42
+
43
+ def self.substring(input, start, stop, reverse)
44
+ return nil if start >= stop || input.size < stop
45
+
46
+ return nil if input.chars.any? { |c| c.ord > 127 }
47
+
48
+ return input[start...stop] unless reverse
49
+
50
+ r_start = input.size - stop
51
+ r_stop = input.size - start
52
+ input[r_start...r_stop]
53
+ end
54
+
55
+ # stringEquals(value1: string, value2: string) bool
56
+ def self.string_equals?(value1, value2)
57
+ value1 == value2
58
+ end
59
+
60
+ # booleanEquals(value1: bool, value2: bool) bool
61
+ def self.boolean_equals?(value1, value2)
62
+ value1 == value2
63
+ end
64
+
65
+ # uriEncode(value: string) string
66
+ def self.uri_encode(value)
67
+ CGI.escape(value.encode('UTF-8')).gsub('+', '%20').gsub('%7E', '~')
68
+ end
69
+
70
+ # parseUrl(value: string) Option<URL>
71
+ def self.parse_url(value)
72
+ URL.new(value).as_json
73
+ rescue ArgumentError, URI::InvalidURIError
74
+ nil
75
+ end
76
+
77
+ # isValidHostLabel(value: string, allowSubDomains: bool) bool
78
+ def self.valid_host_label?(value, allow_sub_domains = false)
79
+ return false if value.empty?
80
+
81
+ if allow_sub_domains
82
+ labels = value.split('.')
83
+ return labels.all? { |l| valid_host_label?(l) }
84
+ end
85
+
86
+ value =~ /\A(?!-)[a-zA-Z0-9-]{1,63}(?<!-)\z/
87
+ end
88
+
89
+ # AWS
90
+
91
+ # aws.partition(value: string) Option<Partition>
92
+ def self.aws_partition(value)
93
+ partition =
94
+ Aws::Partitions.find { |p| p.region?(value) } ||
95
+ Aws::Partitions.find { |p| value.match(p.region_regex) } ||
96
+ Aws::Partitions.find { |p| p.name == 'aws' }
97
+
98
+ return nil unless partition
99
+
100
+ partition.metadata
101
+ end
102
+
103
+ # aws.parseArn(value: string) Option<ARN>
104
+ def self.aws_parse_arn(value)
105
+ arn = Aws::ARNParser.parse(value)
106
+ json = arn.as_json
107
+ # HACK: because of poor naming and also requirement of splitting
108
+ resource = json.delete('resource')
109
+ json['resourceId'] = resource.split(%r{[:\/]}, -1)
110
+ json
111
+ rescue Aws::Errors::InvalidARNError
112
+ nil
113
+ end
114
+
115
+ # aws.isVirtualHostableS3Bucket(value: string, allowSubDomains: bool) bool
116
+ def self.aws_virtual_hostable_s3_bucket?(value, allow_sub_domains = false)
117
+ !!(value.size < 64 &&
118
+ # regular naming rules
119
+ value =~ /^[a-z0-9][a-z0-9\-#{'.' if allow_sub_domains}]+[a-z0-9]$/ &&
120
+ # not IP address
121
+ value !~ /(\d+\.){3}\d+/ &&
122
+ # no dash and hyphen together
123
+ value !~ /[.-]{2}/)
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class Reference
7
+ def initialize(ref:)
8
+ @ref = ref
9
+ end
10
+
11
+ attr_reader :ref
12
+
13
+ def resolve(parameters, assigns)
14
+ if parameters.class.singleton_class::PARAM_MAP.key?(@ref)
15
+ member_name = parameters.class.singleton_class::PARAM_MAP[@ref]
16
+ parameters[member_name]
17
+ elsif assigns.key?(@ref)
18
+ assigns[@ref]
19
+ else
20
+ raise ArgumentError,
21
+ "Reference #{@ref} is not a param or an assigned value."
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class Rule
7
+ # Resolves a value that is a function, reference, or template string.
8
+ def resolve_value(value, parameters, assigns)
9
+ if value.is_a?(Hash) && value['fn']
10
+ Function.new(fn: value['fn'], argv: value['argv'])
11
+ .call(parameters, assigns)
12
+ elsif value.is_a?(Hash) && value['ref']
13
+ Reference.new(ref: value['ref']).resolve(parameters, assigns)
14
+ else
15
+ Templater.resolve(value, parameters, assigns)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # @api private
6
+ class RuleSet
7
+ def initialize(version:, service_id:, parameters:, rules:)
8
+ @version = version
9
+ @service_id = service_id
10
+ @parameters = parameters
11
+ @rules = RuleSet.rules_from_json(rules || [])
12
+ end
13
+
14
+ attr_reader :version
15
+ attr_reader :service_id
16
+ attr_reader :parameters
17
+ attr_reader :rules
18
+
19
+ def self.rules_from_json(rules_json)
20
+ rules_json.each.with_object([]) do |rule, rules|
21
+ if rule['type'] == 'endpoint'
22
+ rules << EndpointRule.new(
23
+ conditions: rule['conditions'],
24
+ endpoint: rule['endpoint'],
25
+ documentation: rule['documentation']
26
+ )
27
+ elsif rule['type'] == 'error'
28
+ rules << ErrorRule.new(
29
+ conditions: rule['conditions'],
30
+ error: rule['error'],
31
+ documentation: rule['documentation']
32
+ )
33
+ elsif rule['type'] == 'tree'
34
+ rules << TreeRule.new(
35
+ conditions: rule['conditions'],
36
+ rules: rule['rules'],
37
+ documentation: rule['documentation']
38
+ )
39
+ else
40
+ # should not happen
41
+ raise "Unknown endpoint rule type: #{rule}"
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ module Aws
2
+ module Endpoints
3
+ # @api private
4
+ class RulesProvider
5
+ def initialize(rule_set)
6
+ @rule_set = rule_set
7
+ end
8
+
9
+ def resolve_endpoint(parameters)
10
+ obj = resolve_rules(parameters)
11
+ case obj
12
+ when Endpoint
13
+ obj
14
+ when ArgumentError
15
+ raise obj
16
+ else
17
+ raise ArgumentError, 'No endpoint could be resolved'
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def resolve_rules(parameters)
24
+ @rule_set.rules.each do |rule|
25
+ output = rule.match(parameters)
26
+ return output if output
27
+ end
28
+ nil
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aws
4
+ module Endpoints
5
+ # Does substitutions for templated endpoint strings
6
+ # @api private
7
+ module Templater
8
+ class << self
9
+ def resolve(string, parameters, assigns)
10
+ # scans for strings in curly brackets {}
11
+ string.scan(/\{.+?\}/).each do |capture|
12
+ value = capture[1..-2] # strips curly brackets
13
+ string = string.gsub(capture, replace(value, parameters, assigns))
14
+ end
15
+ string
16
+ end
17
+
18
+ private
19
+
20
+ # Replaces the captured value with values from parameters or assign
21
+ def replace(capture, parameters, assigns)
22
+ # Pound sigil is used for getAttr calls
23
+ indexes = capture.split('#')
24
+
25
+ # no sigil found, just do substitution
26
+ if indexes.size == 1
27
+ extract_value(capture, parameters, assigns)
28
+ # sigil was found, need to call getAttr
29
+ elsif indexes.size == 2
30
+ ref, property = indexes
31
+ param = extract_value(ref, parameters, assigns)
32
+ Matchers.attr(param, property)
33
+ else
34
+ raise "Invalid templatable value: #{capture}"
35
+ end
36
+ end
37
+
38
+ # Checks both parameters and assigns hash for the referenced value
39
+ def extract_value(key, parameters, assigns)
40
+ if assigns.key?(key)
41
+ assigns[key]
42
+ elsif parameters.class.singleton_class::PARAM_MAP.key?(key)
43
+ member_name = parameters.class.singleton_class::PARAM_MAP[key]
44
+ parameters[member_name]
45
+ else
46
+ raise "Templatable value not found: #{key}"
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end