aws-sdk-core 2.2.37 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -115,6 +115,7 @@ module Aws
115
115
  autoload :Pager, 'aws-sdk-core/pager'
116
116
  autoload :ParamConverter, 'aws-sdk-core/param_converter'
117
117
  autoload :ParamValidator, 'aws-sdk-core/param_validator'
118
+ autoload :Partitions, 'aws-sdk-core/partitions'
118
119
  autoload :RefreshingCredentials, 'aws-sdk-core/refreshing_credentials'
119
120
  autoload :Service, 'aws-sdk-core/service'
120
121
  autoload :SharedCredentials, 'aws-sdk-core/shared_credentials'
@@ -169,6 +170,7 @@ module Aws
169
170
  autoload :RequestSigner, 'aws-sdk-core/plugins/request_signer'
170
171
  autoload :RetryErrors, 'aws-sdk-core/plugins/retry_errors'
171
172
  autoload :Route53IdFix, 'aws-sdk-core/plugins/route_53_id_fix'
173
+ autoload :S3Accelerate, 'aws-sdk-core/plugins/s3_accelerate'
172
174
  autoload :S3BucketDns, 'aws-sdk-core/plugins/s3_bucket_dns'
173
175
  autoload :S3Expect100Continue, 'aws-sdk-core/plugins/s3_expect_100_continue'
174
176
  autoload :S3GetBucketLocationFix, 'aws-sdk-core/plugins/s3_get_bucket_location_fix'
@@ -279,6 +281,59 @@ module Aws
279
281
  end
280
282
  end
281
283
 
284
+ # Return the partition with the given name. A partition describes
285
+ # the services and regions available in that partition.
286
+ #
287
+ # aws = Aws.partition('aws')
288
+ #
289
+ # puts "Regions available in the aws partition:\n"
290
+ # aws.regions.each do |region|
291
+ # puts region.name
292
+ # end
293
+ #
294
+ # puts "Services available in the aws partition:\n"
295
+ # aws.services.each do |services|
296
+ # puts services.name
297
+ # end
298
+ #
299
+ # See {Partitions} for more information and examples.
300
+ #
301
+ # @param [String] partition_name The name of the partition to return.
302
+ # Valid names include "aws", "aws-cn", and "aws-us-gov".
303
+ #
304
+ # @return [Partitions::Partition]
305
+ #
306
+ # @raise [ArgumentError] Raises an `ArgumentError` if a partition is
307
+ # not found with the given name. The error message contains a list
308
+ # of valid partition names.
309
+ def partition(partition_name)
310
+ Partitions.default_list.partition(partition_name)
311
+ end
312
+
313
+ # Return an array of partitions. A partition describes
314
+ # the services and regions available in that partition.
315
+ #
316
+ # Aws.partitions.each do |partition|
317
+ #
318
+ # puts "Regions available in #{partition.name}:\n"
319
+ # partition.regions.each do |region|
320
+ # puts region.name
321
+ # end
322
+ #
323
+ # puts "Services available in #{partition.name}:\n"
324
+ # partition.services.each do |service|
325
+ # puts service.name
326
+ # end
327
+ # end
328
+ #
329
+ # See {Partitions} for more information and examples.
330
+ #
331
+ # @return [Array<Partitions::Partition>] Returns an array of all
332
+ # known partitions.
333
+ def partitions
334
+ Partitions.default_list.partitions
335
+ end
336
+
282
337
  # The SDK ships with a ca certificate bundle to use when verifying SSL
283
338
  # peer certificates. By default, this cert bundle is *NOT* used. The
284
339
  # SDK will rely on the default cert available to OpenSSL. This ensures
@@ -145,9 +145,30 @@ module Aws
145
145
 
146
146
  api('s3') do |api|
147
147
  api['metadata'].delete('signatureVersion')
148
+ if ENV['DOCSTRINGS']
149
+ api['shapes']['AccelerateBoolean'] = { 'type' => 'boolean' }
150
+ api['operations'].each do |operation_name, operation|
151
+ next if %w(CreateBucket ListBuckets DeleteBucket).include?(operation_name)
152
+ if input_ref = operation['input']
153
+ input_shape = api['shapes'][input_ref['shape']]
154
+ input_shape['members']['UseAccelerateEndpoint'] = {
155
+ 'shape' => 'AccelerateBoolean'
156
+ }
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ doc('s3') do |docs|
163
+ if ENV['DOCSTRINGS']
164
+ docs['shapes']['AccelerateBoolean'] = {}
165
+ docs['shapes']['AccelerateBoolean']['refs'] = {}
166
+ docs['shapes']['AccelerateBoolean']['base'] = 'When <tt>true</tt>, the "https://BUCKETNAME.s3-accelerate.amazonaws.com" endpoint will be used.'
167
+ end
148
168
  end
149
169
 
150
170
  plugins('s3', add: %w(
171
+ Aws::Plugins::S3Accelerate
151
172
  Aws::Plugins::S3BucketDns
152
173
  Aws::Plugins::S3Expect100Continue
153
174
  Aws::Plugins::S3Http200Errors
@@ -44,7 +44,7 @@ module Aws
44
44
  end
45
45
  when ListShape then list(ref, i, visited)
46
46
  when MapShape then map(ref, i, visited)
47
- when BooleanShape then "true"
47
+ when BooleanShape then "false"
48
48
  when IntegerShape then '1'
49
49
  when FloatShape then '1.0'
50
50
  when StringShape then string(ref)
@@ -2,32 +2,91 @@ module Aws
2
2
  # @api private
3
3
  class EndpointProvider
4
4
 
5
- # @api private
6
- PATH = File.join(File.dirname(__FILE__), '..', '..', 'endpoints.json')
5
+ def initialize(rules)
6
+ @rules = rules
7
+ end
7
8
 
8
- # @api private
9
- RULES = Json.load_file(PATH)['endpoints']
9
+ def resolve(region, service)
10
+ "https://" + endpoint_for(region, service)
11
+ end
10
12
 
11
- class << self
13
+ def signing_region(region, service)
14
+ get_partition(region).
15
+ fetch("services", {}).
16
+ fetch(service, {}).
17
+ fetch("endpoints", {}).
18
+ fetch(region, {}).
19
+ fetch("credentialScope", {}).
20
+ fetch("region", region)
21
+ end
12
22
 
13
- def resolve(region, service)
14
- keys(region, service).each do |key|
15
- if match = RULES[key]
16
- return expand(match['endpoint'], region.to_s, service.to_s)
17
- end
18
- end
23
+ private
24
+
25
+ def endpoint_for(region, service)
26
+ partition = get_partition(region)
27
+ endpoint = default_endpoint(partition, service, region)
28
+ service_cfg = partition.fetch("services", {}).fetch(service, {})
29
+
30
+ # Check for service-level default endpoint.
31
+ endpoint = service_cfg.fetch("defaults", {}).fetch("hostname", endpoint)
32
+
33
+ # Check for global endpoint.
34
+ if service_cfg["isRegionalized"] == false
35
+ region = service_cfg.fetch("partitionEndpoint", region)
19
36
  end
20
37
 
21
- private
38
+ # Check for service/region level endpoint.
39
+ endpoint = service_cfg.fetch("endpoints", {}).
40
+ fetch(region, {}).fetch("hostname", endpoint)
41
+
42
+ endpoint
43
+ end
44
+
45
+ def default_endpoint(partition, service, region)
46
+ hostname_template = partition["defaults"]["hostname"]
47
+ hostname_template.
48
+ sub('{region}', region).
49
+ sub('{service}', service).
50
+ sub('{dnsSuffix}', partition["dnsSuffix"])
51
+ end
52
+
53
+ def get_partition(region)
54
+ partition_containing_region(region) ||
55
+ partition_matching_region(region) ||
56
+ default_partition
57
+ end
22
58
 
23
- def keys(region, service)
24
- ["#{region}/#{service}", "#{region}/*", "*/#{service}", "*/*"]
59
+ def partition_containing_region(region)
60
+ @rules['partitions'].find do |p|
61
+ p['regions'].key?(region)
25
62
  end
63
+ end
26
64
 
27
- def expand(pattern, region, service)
28
- 'https://' + pattern.sub('{region}', region).sub('{service}', service)
65
+ def partition_matching_region(region)
66
+ @rules['partitions'].find do |p|
67
+ region.match(p["regionRegex"]) ||
68
+ p['services'].values.find { |svc| svc['endpoints'].key?(region) }
29
69
  end
70
+ end
30
71
 
72
+ def default_partition
73
+ @rules['partitions'].find { |p| p["partition"] == "aws" } ||
74
+ @rules['partitions'].first
31
75
  end
76
+
77
+ class << self
78
+
79
+ def resolve(region, service)
80
+ DEFAULT_PROVIDER.resolve(region, service)
81
+ end
82
+
83
+ def signing_region(region, service)
84
+ DEFAULT_PROVIDER.signing_region(region, service)
85
+ end
86
+
87
+ end
88
+
89
+ DEFAULT_PROVIDER = EndpointProvider.new(Partitions.defaults)
90
+
32
91
  end
33
92
  end
@@ -0,0 +1,174 @@
1
+ module Aws
2
+
3
+ # A {Partition} is a group of AWS {Region} and {Service} objects. You
4
+ # can use a partition to determine what services are available in a region,
5
+ # or what regions a service is available in.
6
+ #
7
+ # ## Partitions
8
+ #
9
+ # **AWS accounts are scoped to a single partition**. You can get a partition
10
+ # by name. Valid partition names include:
11
+ #
12
+ # * `"aws"` - Public AWS partition
13
+ # * `"aws-cn"` - AWS China
14
+ # * `"aws-us-gov"` - AWS GovCloud
15
+ #
16
+ # To get a partition by name:
17
+ #
18
+ # aws = Aws.partition('aws')
19
+ #
20
+ # You can also enumerate all partitions:
21
+ #
22
+ # Aws.partitions.each do |partition|
23
+ # puts partition.name
24
+ # end
25
+ #
26
+ # ## Regions
27
+ #
28
+ # A {Partition} is divided up into one or more regions. For example, the
29
+ # "aws" partition contains, "us-east-1", "us-west-1", etc. You can get
30
+ # a region by name. Calling {Partition#region} will return an instance
31
+ # of {Region}.
32
+ #
33
+ # region = Aws.partition('aws').region('us-east-1')
34
+ # region.name
35
+ # #=> "us-east-1"
36
+ #
37
+ # You can also enumerate all regions within a partition:
38
+ #
39
+ # Aws.partition('aws').regions.each do |region|
40
+ # puts region.name
41
+ # end
42
+ #
43
+ # Each {Region} object has a name, description and a list of services
44
+ # available to that region:
45
+ #
46
+ # us_west_2 = Aws.partition('aws').region('us-west-2')
47
+ #
48
+ # us_west_2.name #=> "us-west-2"
49
+ # us_west_2.description #=> "US West (Oregon)"
50
+ # us_west_2.partition_name "aws"
51
+ # us_west_2.services #=> #<Set: {"APIGateway", "AutoScaling", ... }
52
+ #
53
+ # To know if a service is available within a region, you can call `#include?`
54
+ # on the set of service names:
55
+ #
56
+ # region.services.include?('DynamoDB') #=> true/false
57
+ #
58
+ # The service name should be the service's module name as used by
59
+ # the AWS SDK for Ruby. To find the complete list of supported
60
+ # service names, see {Partition#services}.
61
+ #
62
+ # Its also possible to enumerate every service for every region in
63
+ # every partition.
64
+ #
65
+ # Aws.partitions.each do |partition|
66
+ # partition.regions.each do |region|
67
+ # region.services.each do |service_name|
68
+ # puts "#{partition.name} -> #{region.name} -> #{service_name}"
69
+ # end
70
+ # end
71
+ # end
72
+ #
73
+ # ## Services
74
+ #
75
+ # A {Partition} has a list of services available. You can get a
76
+ # single {Service} by name:
77
+ #
78
+ # Aws.partition('aws').service('DynamoDB')
79
+ #
80
+ # You can also enumerate all services in a partition:
81
+ #
82
+ # Aws.partition('aws').services.each do |service|
83
+ # puts service.name
84
+ # end
85
+ #
86
+ # Each {Service} object has a name, and information about regions
87
+ # that service is available in.
88
+ #
89
+ # service.name #=> "DynamoDB"
90
+ # service.partition_name #=> "aws"
91
+ # service.regions #=> #<Set: {"us-east-1", "us-west-1", ... }
92
+ #
93
+ # Some services have multiple regions, and others have a single partition
94
+ # wide region. For example, {Aws::IAM} has a single region in the "aws"
95
+ # partition. The {Service#regionalized?} method indicates when this is
96
+ # the case.
97
+ #
98
+ # iam = Aws.partition('aws').service('IAM')
99
+ #
100
+ # iam.regionalized? #=> false
101
+ # service.partition_region #=> "us-east-1"
102
+ #
103
+ # Its also possible to enumerate every region for every service in
104
+ # every partition.
105
+ #
106
+ # Aws.partitions.each do |partition|
107
+ # partition.services.each do |service|
108
+ # service.regions.each do |region_name|
109
+ # puts "#{partition.name} -> #{region_name} -> #{service.name}"
110
+ # end
111
+ # end
112
+ # end
113
+ #
114
+ # ## Service Names
115
+ #
116
+ # {Service} names are those used by the the AWS SDK for Ruby. They
117
+ # correspond to the service's module.
118
+ #
119
+ module Partitions
120
+
121
+ autoload :Partition, 'aws-sdk-core/partitions/partition'
122
+ autoload :PartitionList, 'aws-sdk-core/partitions/partition_list'
123
+ autoload :Region, 'aws-sdk-core/partitions/region'
124
+ autoload :Service, 'aws-sdk-core/partitions/service'
125
+
126
+ class << self
127
+
128
+ # @param [Hash] new_partitions
129
+ # @api private
130
+ def add(new_partitions)
131
+ new_partitions['partitions'].each do |partition|
132
+ default_list.add_partition(Partition.build(partition))
133
+ defaults['partitions'] << partition
134
+ end
135
+ end
136
+
137
+ # @api private
138
+ def clear
139
+ default_list.clear
140
+ defaults['partitions'].clear
141
+ end
142
+
143
+ # @return [Hash]
144
+ # @api private
145
+ def defaults
146
+ @defaults ||= begin
147
+ path = File.join(File.dirname(__FILE__), '..', '..', 'endpoints.json')
148
+ Aws::Json.load_file(path)
149
+ end
150
+ end
151
+
152
+ # @return [PartitionList]
153
+ # @api priviate
154
+ def default_list
155
+ @default_list ||= PartitionList.build(defaults)
156
+ end
157
+
158
+ # @return [Hash<String,String>] Returns a map of service module names
159
+ # to their id as used in the endpoints.json document.
160
+ # @api private
161
+ def service_ids
162
+ @service_ids ||= begin
163
+ services = "#{File.dirname(__FILE__)}/../../service-models.json"
164
+ services = Aws::Json.load_file(services)
165
+ services.inject({}) do |ids, (name, svc)|
166
+ ids[name] = svc['endpoint'] #if svc['endpoint']
167
+ ids
168
+ end
169
+ end
170
+ end
171
+
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,95 @@
1
+ module Aws
2
+ module Partitions
3
+ class Partition
4
+
5
+ # @option options [required, String] :name
6
+ # @option options [required, Hash<String,Region>] :regions
7
+ # @option options [required, Hash<String,Service>] :services
8
+ # @api private
9
+ def initialize(options = {})
10
+ @name = options[:name]
11
+ @regions = options[:regions]
12
+ @services = options[:services]
13
+ end
14
+
15
+ # @return [String] The partition name, e.g. "aws", "aws-cn", "aws-us-gov".
16
+ attr_reader :name
17
+
18
+ # @param [String] region_name The name of the region, e.g. "us-east-1".
19
+ # @return [Region]
20
+ # @raise [ArgumentError] Raises `ArgumentError` for unknown region name.
21
+ def region(region_name)
22
+ if @regions.key?(region_name)
23
+ @regions[region_name]
24
+ else
25
+ msg = "invalid region name #{region_name.inspect}; valid region "
26
+ msg << "names include %s" % [@regions.keys.join(', ')]
27
+ raise ArgumentError, msg
28
+ end
29
+ end
30
+
31
+ # @return [Array<Region>]
32
+ def regions
33
+ @regions.values
34
+ end
35
+
36
+ # @param [String] service_name The service module name.
37
+ # @return [Service]
38
+ # @raise [ArgumentError] Raises `ArgumentError` for unknown service name.
39
+ def service(service_name)
40
+ if @services.key?(service_name)
41
+ @services[service_name]
42
+ else
43
+ msg = "invalid service name #{service_name.inspect}; valid service "
44
+ msg << "names include %s" % [@services.keys.join(', ')]
45
+ raise ArgumentError, msg
46
+ end
47
+ end
48
+
49
+ # @return [Array<Service>]
50
+ def services
51
+ @services.values
52
+ end
53
+
54
+ class << self
55
+
56
+ # @api private
57
+ def build(partition)
58
+ Partition.new(
59
+ name: partition['partition'],
60
+ regions: build_regions(partition),
61
+ services: build_services(partition),
62
+ )
63
+ end
64
+
65
+ private
66
+
67
+ # @param [Hash] partition
68
+ # @return [Hash<String,Region>]
69
+ def build_regions(partition)
70
+ partition['regions'].inject({}) do |regions, (region_name, region)|
71
+ unless region_name == "#{partition['partition']}-global"
72
+ regions[region_name] = Region.build(region_name, region, partition)
73
+ end
74
+ regions
75
+ end
76
+ end
77
+
78
+ # @param [Hash] partition
79
+ # @return [Hash<String,Service>]
80
+ def build_services(partition)
81
+ Partitions.service_ids.inject({}) do |services, (svc_name, svc_id)|
82
+ if partition['services'].key?(svc_id)
83
+ svc_data = partition['services'][svc_id]
84
+ services[svc_name] = Service.build(svc_name, svc_data, partition)
85
+ else
86
+ services[svc_name] = Service.build(svc_name, {'endpoints' => {}}, partition)
87
+ end
88
+ services
89
+ end
90
+ end
91
+
92
+ end
93
+ end
94
+ end
95
+ end