aws-partitions 1.479.0 → 1.946.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2414 -0
- data/VERSION +1 -1
- data/lib/aws-partitions/endpoint_provider.rb +155 -33
- data/lib/aws-partitions/partition.rb +10 -2
- data/lib/aws-partitions/partition_list.rb +50 -0
- data/lib/aws-partitions/service.rb +27 -0
- data/lib/aws-partitions.rb +139 -4
- data/partitions-metadata.json +220 -0
- data/partitions.json +23268 -4815
- metadata +9 -8
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.946.0
|
@@ -37,31 +37,108 @@ module Aws
|
|
37
37
|
# "monitoring" for cloudwatch.
|
38
38
|
# @param [String] sts_regional_endpoints [STS only] Whether to use
|
39
39
|
# `legacy` (global endpoint for legacy regions) or `regional` mode for
|
40
|
-
#
|
40
|
+
# using regional endpoint for supported regions except 'aws-global'
|
41
|
+
# @param [Hash] variants Endpoint variants such as 'fips' or 'dualstack'
|
42
|
+
# @option variants [Boolean] :dualstack When true, resolve a dualstack
|
43
|
+
# endpoint.
|
44
|
+
# @option variants [Boolean] :fips When true, resolve a FIPS endpoint.
|
41
45
|
# @api private Use the static class methods instead.
|
42
|
-
def resolve(region, service, sts_regional_endpoints)
|
43
|
-
'https://' + endpoint_for(region, service, sts_regional_endpoints)
|
46
|
+
def resolve(region, service, sts_regional_endpoints, variants)
|
47
|
+
'https://' + endpoint_for(region, service, build_is_global_fn(sts_regional_endpoints), variants)
|
44
48
|
end
|
45
49
|
|
46
50
|
# @api private Use the static class methods instead.
|
47
|
-
def signing_region(region, service)
|
48
|
-
|
49
|
-
.fetch('services', {})
|
50
|
-
.fetch(service, {})
|
51
|
-
.fetch('endpoints', {})
|
52
|
-
.fetch(region, {})
|
53
|
-
.fetch('credentialScope', {})
|
51
|
+
def signing_region(region, service, sts_regional_endpoints)
|
52
|
+
credential_scope(region, service, build_is_global_fn(sts_regional_endpoints))
|
54
53
|
.fetch('region', region)
|
55
54
|
end
|
56
55
|
|
57
56
|
# @api private Use the static class methods instead.
|
58
|
-
def
|
59
|
-
|
57
|
+
def signing_service(region, service)
|
58
|
+
# don't default to the service name
|
59
|
+
# signers should prefer the api metadata's signingName
|
60
|
+
# if no service is set in the credentialScope
|
61
|
+
credential_scope(region, service, build_is_global_fn('regional'))
|
62
|
+
.fetch('service', nil)
|
63
|
+
end
|
64
|
+
|
65
|
+
# @param [String] region The region used to fetch the partition.
|
66
|
+
# @param [String] service Used only if dualstack is true. Used to find a
|
67
|
+
# DNS suffix for a specific service.
|
68
|
+
# @param [Hash] variants Endpoint variants such as 'fips' or 'dualstack'
|
69
|
+
# @option variants [Boolean] :dualstack When true, resolve a dualstack
|
70
|
+
# endpoint.
|
71
|
+
# @option variants [Boolean] :fips When true, resolve a FIPS endpoint.
|
72
|
+
# @api private Use the static class methods instead.
|
73
|
+
def dns_suffix_for(region, service, variants)
|
74
|
+
if configured_variants?(variants)
|
75
|
+
resolve_variant(region, service, variants)['dnsSuffix']
|
76
|
+
else
|
77
|
+
get_partition(region)['dnsSuffix']
|
78
|
+
end
|
60
79
|
end
|
61
80
|
|
62
81
|
private
|
63
82
|
|
64
|
-
def
|
83
|
+
def configured_variants?(variants)
|
84
|
+
variants.values.any?
|
85
|
+
end
|
86
|
+
|
87
|
+
def fetch_variant(cfg, tags)
|
88
|
+
variants = cfg.fetch('variants', [])
|
89
|
+
variants.find { |v| tags == Set.new(v['tags']) } || {}
|
90
|
+
end
|
91
|
+
|
92
|
+
def resolve_variant(region, service, config_variants)
|
93
|
+
tags = Set.new(config_variants.select { |_k,v| v == true }.map { |k,_v| k.to_s })
|
94
|
+
is_global_fn = build_is_global_fn # ignore legacy STS config for variants
|
95
|
+
|
96
|
+
partition_cfg = get_partition(region)
|
97
|
+
service_cfg = partition_cfg.fetch('services', {})
|
98
|
+
.fetch(service, {})
|
99
|
+
|
100
|
+
endpoints_cfg = service_cfg.fetch('endpoints', {})
|
101
|
+
|
102
|
+
if is_global_fn.call(service, region, endpoints_cfg, service_cfg)
|
103
|
+
region = service_cfg.fetch('partitionEndpoint', region)
|
104
|
+
end
|
105
|
+
|
106
|
+
region_cfg = endpoints_cfg.fetch(region, {})
|
107
|
+
warn_deprecation(service, region) if region_cfg['deprecated']
|
108
|
+
|
109
|
+
partition_defaults = fetch_variant(partition_cfg.fetch('defaults', {}), tags)
|
110
|
+
service_defaults = fetch_variant(service_cfg.fetch('defaults', {}), tags)
|
111
|
+
endpoint_cfg = fetch_variant(region_cfg, tags)
|
112
|
+
|
113
|
+
# merge upwards, preferring values from endpoint > service > partition
|
114
|
+
partition_defaults.merge(service_defaults.merge(endpoint_cfg))
|
115
|
+
end
|
116
|
+
|
117
|
+
def validate_variant!(config_variants, resolved_variant)
|
118
|
+
unless resolved_variant['hostname'] && resolved_variant['dnsSuffix']
|
119
|
+
enabled_variants = config_variants.select { |_k, v| v}.map { |k, _v| k.to_s }.join(', ')
|
120
|
+
raise ArgumentError,
|
121
|
+
"#{enabled_variants} not supported for this region and partition."
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def endpoint_for(region, service, is_global_fn, variants)
|
126
|
+
if configured_variants?(variants)
|
127
|
+
endpoint_with_variants_for(region, service, variants)
|
128
|
+
else
|
129
|
+
endpoint_no_variants_for(region, service, is_global_fn)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def endpoint_with_variants_for(region, service, variants)
|
134
|
+
variant = resolve_variant(region, service, variants)
|
135
|
+
validate_variant!(variants, variant)
|
136
|
+
variant['hostname'].sub('{region}', region)
|
137
|
+
.sub('{service}', service)
|
138
|
+
.sub('{dnsSuffix}', variant['dnsSuffix'])
|
139
|
+
end
|
140
|
+
|
141
|
+
def endpoint_no_variants_for(region, service, is_global_fn)
|
65
142
|
partition = get_partition(region)
|
66
143
|
service_cfg = partition.fetch('services', {}).fetch(service, {})
|
67
144
|
|
@@ -72,33 +149,70 @@ module Aws
|
|
72
149
|
|
73
150
|
endpoints = service_cfg.fetch('endpoints', {})
|
74
151
|
|
75
|
-
# Check for sts legacy behavior
|
76
|
-
sts_legacy = service == 'sts' &&
|
77
|
-
sts_regional_endpoints == 'legacy' &&
|
78
|
-
STS_LEGACY_REGIONS.include?(region)
|
79
|
-
|
80
|
-
is_global = !endpoints.key?(region) &&
|
81
|
-
service_cfg['isRegionalized'] == false
|
82
|
-
|
83
152
|
# Check for global endpoint.
|
84
|
-
if
|
153
|
+
if is_global_fn.call(service, region, endpoints, service_cfg)
|
85
154
|
region = service_cfg.fetch('partitionEndpoint', region)
|
86
155
|
end
|
87
156
|
|
88
157
|
# Check for service/region level endpoint.
|
89
|
-
|
158
|
+
region_cfg = endpoints
|
90
159
|
.fetch(region, {})
|
160
|
+
endpoint = region_cfg
|
91
161
|
.fetch('hostname', default_endpoint)
|
92
162
|
|
163
|
+
warn_deprecation(service, region) if region_cfg['deprecated']
|
164
|
+
|
93
165
|
# Replace placeholders from the endpoints
|
94
166
|
endpoint.sub('{region}', region)
|
95
167
|
.sub('{service}', service)
|
96
168
|
.sub('{dnsSuffix}', partition['dnsSuffix'])
|
97
169
|
end
|
98
170
|
|
99
|
-
def
|
100
|
-
|
101
|
-
|
171
|
+
def warn_deprecation(service, region)
|
172
|
+
warn("The endpoint for service: #{service}, region: #{region}"\
|
173
|
+
' is deprecated.')
|
174
|
+
end
|
175
|
+
|
176
|
+
# returns a callable that takes a region
|
177
|
+
# and returns true if the service is global
|
178
|
+
def build_is_global_fn(sts_regional_endpoints='regional')
|
179
|
+
lambda do |service, region, endpoints, service_cfg|
|
180
|
+
# Check for sts legacy behavior
|
181
|
+
sts_legacy = service == 'sts' &&
|
182
|
+
sts_regional_endpoints == 'legacy' &&
|
183
|
+
STS_LEGACY_REGIONS.include?(region)
|
184
|
+
|
185
|
+
is_global = !endpoints.key?(region) &&
|
186
|
+
service_cfg['isRegionalized'] == false
|
187
|
+
|
188
|
+
sts_legacy || is_global
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def credential_scope(region, service, is_global_fn)
|
193
|
+
partition = get_partition(region)
|
194
|
+
service_cfg = partition.fetch('services', {})
|
195
|
+
.fetch(service, {})
|
196
|
+
endpoints = service_cfg.fetch('endpoints', {})
|
197
|
+
|
198
|
+
# Check for global endpoint.
|
199
|
+
if is_global_fn.call(service, region, endpoints, service_cfg)
|
200
|
+
region = service_cfg.fetch('partitionEndpoint', region)
|
201
|
+
end
|
202
|
+
|
203
|
+
default_credential_scope = service_cfg
|
204
|
+
.fetch('defaults', {})
|
205
|
+
.fetch('credentialScope', {})
|
206
|
+
|
207
|
+
endpoints
|
208
|
+
.fetch(region, {})
|
209
|
+
.fetch('credentialScope', default_credential_scope)
|
210
|
+
end
|
211
|
+
|
212
|
+
def get_partition(region_or_partition)
|
213
|
+
partition_containing_region(region_or_partition) ||
|
214
|
+
partition_matching_region(region_or_partition) ||
|
215
|
+
partition_matching_name(region_or_partition) ||
|
102
216
|
default_partition
|
103
217
|
end
|
104
218
|
|
@@ -110,29 +224,37 @@ module Aws
|
|
110
224
|
|
111
225
|
def partition_matching_region(region)
|
112
226
|
@rules['partitions'].find do |p|
|
113
|
-
region.match(p['regionRegex']) ||
|
227
|
+
p['regionRegex'] && region.match(p['regionRegex']) ||
|
114
228
|
p['services'].values.find do |svc|
|
115
229
|
svc['endpoints'].key?(region) if svc.key?('endpoints')
|
116
230
|
end
|
117
231
|
end
|
118
232
|
end
|
119
233
|
|
234
|
+
def partition_matching_name(partition_name)
|
235
|
+
@rules['partitions'].find { |p| p['partition'] == partition_name }
|
236
|
+
end
|
237
|
+
|
120
238
|
def default_partition
|
121
239
|
@rules['partitions'].find { |p| p['partition'] == 'aws' } ||
|
122
240
|
@rules['partitions'].first
|
123
241
|
end
|
124
242
|
|
125
243
|
class << self
|
126
|
-
def resolve(region, service,
|
127
|
-
default_provider.resolve(region, service,
|
244
|
+
def resolve(region, service, sts_endpoint = 'regional', variants = {})
|
245
|
+
default_provider.resolve(region, service, sts_endpoint, variants)
|
246
|
+
end
|
247
|
+
|
248
|
+
def signing_region(region, service, sts_regional_endpoints = 'regional')
|
249
|
+
default_provider.signing_region(region, service, sts_regional_endpoints)
|
128
250
|
end
|
129
251
|
|
130
|
-
def
|
131
|
-
default_provider.
|
252
|
+
def signing_service(region, service)
|
253
|
+
default_provider.signing_service(region, service)
|
132
254
|
end
|
133
255
|
|
134
|
-
def dns_suffix_for(region)
|
135
|
-
default_provider.dns_suffix_for(region)
|
256
|
+
def dns_suffix_for(region, service = nil, variants = {})
|
257
|
+
default_provider.dns_suffix_for(region, service, variants)
|
136
258
|
end
|
137
259
|
|
138
260
|
private
|
@@ -10,12 +10,20 @@ module Aws
|
|
10
10
|
def initialize(options = {})
|
11
11
|
@name = options[:name]
|
12
12
|
@regions = options[:regions]
|
13
|
+
@region_regex = options[:region_regex]
|
13
14
|
@services = options[:services]
|
15
|
+
@metadata = options[:metadata]
|
14
16
|
end
|
15
17
|
|
16
18
|
# @return [String] The partition name, e.g. "aws", "aws-cn", "aws-us-gov".
|
17
19
|
attr_reader :name
|
18
20
|
|
21
|
+
# @return [String] The regex representing the region format.
|
22
|
+
attr_reader :region_regex
|
23
|
+
|
24
|
+
# @return [Metadata] The metadata for the partition.
|
25
|
+
attr_reader :metadata
|
26
|
+
|
19
27
|
# @param [String] region_name The name of the region, e.g. "us-east-1".
|
20
28
|
# @return [Region]
|
21
29
|
# @raise [ArgumentError] Raises `ArgumentError` for unknown region name.
|
@@ -70,6 +78,7 @@ module Aws
|
|
70
78
|
Partition.new(
|
71
79
|
name: partition['partition'],
|
72
80
|
regions: build_regions(partition),
|
81
|
+
region_regex: partition['regionRegex'],
|
73
82
|
services: build_services(partition)
|
74
83
|
)
|
75
84
|
end
|
@@ -79,8 +88,7 @@ module Aws
|
|
79
88
|
# @param [Hash] partition
|
80
89
|
# @return [Hash<String,Region>]
|
81
90
|
def build_regions(partition)
|
82
|
-
partition['regions'].each_with_object({}) do
|
83
|
-
|(region_name, region), regions|
|
91
|
+
partition['regions'].each_with_object({}) do |(region_name, region), regions|
|
84
92
|
next if region_name == "#{partition['partition']}-global"
|
85
93
|
|
86
94
|
regions[region_name] = Region.build(
|
@@ -42,12 +42,62 @@ module Aws
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
# @param [Partition] partitions_metadata
|
46
|
+
# @api private
|
47
|
+
def merge_metadata(partitions_metadata)
|
48
|
+
partitions_metadata['partitions'].each do |partition_metadata|
|
49
|
+
outputs = partition_metadata['outputs']
|
50
|
+
|
51
|
+
if existing = @partitions[partition_metadata['id']]
|
52
|
+
@partitions[partition_metadata['id']] = Partition.new(
|
53
|
+
name: existing.name,
|
54
|
+
regions: build_metadata_regions(
|
55
|
+
partition_metadata['id'],
|
56
|
+
partition_metadata['regions'],
|
57
|
+
existing),
|
58
|
+
region_regex: partition_metadata['regionRegex'],
|
59
|
+
services: existing.services.each_with_object({}) do |s, services|
|
60
|
+
services[s.name] = s
|
61
|
+
end,
|
62
|
+
metadata: outputs
|
63
|
+
)
|
64
|
+
else
|
65
|
+
@partitions[partition_metadata['id']] = Partition.new(
|
66
|
+
name: partition_metadata['id'],
|
67
|
+
regions: build_metadata_regions(
|
68
|
+
partition_metadata['id'], partition_metadata['regions']
|
69
|
+
),
|
70
|
+
region_regex: partition_metadata['regionRegex'],
|
71
|
+
services: {},
|
72
|
+
metadata: outputs
|
73
|
+
)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
45
78
|
# Removed all partitions.
|
46
79
|
# @api private
|
47
80
|
def clear
|
48
81
|
@partitions = {}
|
49
82
|
end
|
50
83
|
|
84
|
+
private
|
85
|
+
|
86
|
+
def build_metadata_regions(partition_name, metadata_regions, existing = nil)
|
87
|
+
metadata_regions.each_with_object({}) do |(region_name, region), regions|
|
88
|
+
if existing && existing.region?(region_name)
|
89
|
+
regions[region_name] = existing.region(region_name)
|
90
|
+
else
|
91
|
+
regions[region_name] = Region.new(
|
92
|
+
name: region_name,
|
93
|
+
description: region['description'],
|
94
|
+
partition_name: partition_name,
|
95
|
+
services: Set.new
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
51
101
|
class << self
|
52
102
|
|
53
103
|
# @api private
|
@@ -16,6 +16,8 @@ module Aws
|
|
16
16
|
@name = options[:name]
|
17
17
|
@partition_name = options[:partition_name]
|
18
18
|
@regions = options[:regions]
|
19
|
+
@fips_regions = options[:fips_regions]
|
20
|
+
@dualstack_regions = options[:dualstack_regions]
|
19
21
|
@regionalized = options[:regionalized]
|
20
22
|
@partition_region = options[:partition_region]
|
21
23
|
end
|
@@ -31,6 +33,14 @@ module Aws
|
|
31
33
|
# Regions are scoped to the partition.
|
32
34
|
attr_reader :regions
|
33
35
|
|
36
|
+
# @return [Set<String>] The FIPS compatible regions this service is
|
37
|
+
# available in. Regions are scoped to the partition.
|
38
|
+
attr_reader :fips_regions
|
39
|
+
|
40
|
+
# @return [Set<String>] The Dualstack compatible regions this service is
|
41
|
+
# available in. Regions are scoped to the partition.
|
42
|
+
attr_reader :dualstack_regions
|
43
|
+
|
34
44
|
# @return [String,nil] The global patition endpoint for this service.
|
35
45
|
# May be `nil`.
|
36
46
|
attr_reader :partition_region
|
@@ -54,6 +64,8 @@ module Aws
|
|
54
64
|
name: service_name,
|
55
65
|
partition_name: partition['partition'],
|
56
66
|
regions: regions(service, partition),
|
67
|
+
fips_regions: variant_regions('fips', service, partition),
|
68
|
+
dualstack_regions: variant_regions('dualstack', service, partition),
|
57
69
|
regionalized: service['isRegionalized'] != false,
|
58
70
|
partition_region: partition_region(service)
|
59
71
|
)
|
@@ -67,6 +79,21 @@ module Aws
|
|
67
79
|
names - ["#{partition['partition']}-global"]
|
68
80
|
end
|
69
81
|
|
82
|
+
def variant_regions(variant_name, service, partition)
|
83
|
+
svc_endpoints = service.fetch('endpoints', {})
|
84
|
+
names = Set.new
|
85
|
+
svc_endpoints.each do |key, value|
|
86
|
+
variants = value.fetch('variants', [])
|
87
|
+
variants.each do |variant|
|
88
|
+
tags = variant.fetch('tags', [])
|
89
|
+
if tags.include?(variant_name) && partition['regions'].key?(key)
|
90
|
+
names << key
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
names - ["#{partition['partition']}-global"]
|
95
|
+
end
|
96
|
+
|
70
97
|
def partition_region(service)
|
71
98
|
service['partitionEndpoint']
|
72
99
|
end
|