fog-aws 3.9.0 → 3.12.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 +4 -4
- data/CHANGELOG.md +225 -17
- data/README.md +1 -1
- data/fog-aws.gemspec +5 -4
- data/lib/fog/aws/compute.rb +6 -3
- data/lib/fog/aws/credential_fetcher.rb +14 -7
- data/lib/fog/aws/models/compute/security_group.rb +13 -5
- data/lib/fog/aws/models/compute/server.rb +2 -0
- data/lib/fog/aws/models/storage/file.rb +13 -10
- data/lib/fog/aws/parsers/compute/describe_security_groups.rb +18 -4
- data/lib/fog/aws/requests/compute/authorize_security_group_ingress.rb +15 -0
- data/lib/fog/aws/requests/compute/describe_security_groups.rb +2 -0
- data/lib/fog/aws/requests/compute/run_instances.rb +44 -0
- data/lib/fog/aws/requests/storage/delete_multiple_objects.rb +18 -8
- data/lib/fog/aws/requests/storage/get_object.rb +1 -1
- data/lib/fog/aws/storage.rb +42 -3
- data/lib/fog/aws/version.rb +1 -1
- data/tests/credentials_tests.rb +41 -0
- data/tests/models/storage/directory_tests.rb +113 -2
- data/tests/requests/compute/security_group_tests.rb +12 -1
- data/tests/requests/storage/bucket_tests.rb +1 -1
- data/tests/requests/storage/versioning_tests.rb +38 -0
- metadata +11 -22
- data/.gitignore +0 -17
- data/.travis.yml +0 -124
- data/Gemfile +0 -14
- data/Rakefile +0 -14
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/gemfiles/Gemfile-edge +0 -14
- data/gemfiles/Gemfile-ruby-2.0 +0 -7
- data/lib/fog/aws/iam/default_policies.json +0 -1574
- data/lib/fog/aws/iam/default_policy_versions.json +0 -3373
- data/stale.yml +0 -17
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Fog::Aws
|
|
2
2
|
|
|
3
3
|

|
|
4
|
-
[](https://github.com/fog/fog-aws/actions/workflows/ruby.yml)
|
|
5
5
|
[](https://codeclimate.com/github/fog/fog-aws)
|
|
6
6
|
[](https://codeclimate.com/github/fog/fog-aws)
|
|
7
7
|
|
data/fog-aws.gemspec
CHANGED
|
@@ -14,17 +14,18 @@ Gem::Specification.new do |spec|
|
|
|
14
14
|
spec.homepage = "https://github.com/fog/fog-aws"
|
|
15
15
|
spec.license = "MIT"
|
|
16
16
|
|
|
17
|
-
spec.files =
|
|
17
|
+
spec.files = Dir['lib/**/*.rb', 'tests/**/*', 'CHANGELOG.md', 'CONTRIBUTING.md',
|
|
18
|
+
'CONTRIBUTORS.md', 'LICENSE.md', 'README.md', 'fog-aws.gemspec',]
|
|
18
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
19
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
20
21
|
spec.require_paths = ["lib"]
|
|
21
22
|
|
|
22
23
|
spec.required_ruby_version = '>= 2.0.0'
|
|
23
24
|
|
|
24
|
-
spec.add_development_dependency 'bundler'
|
|
25
|
-
spec.add_development_dependency 'github_changelog_generator', '~> 1.
|
|
25
|
+
spec.add_development_dependency 'bundler'
|
|
26
|
+
spec.add_development_dependency 'github_changelog_generator', '~> 1.16'
|
|
26
27
|
spec.add_development_dependency 'rake', '>= 12.3.3'
|
|
27
|
-
spec.add_development_dependency 'rubyzip', '~>
|
|
28
|
+
spec.add_development_dependency 'rubyzip', '~> 2.3.0'
|
|
28
29
|
spec.add_development_dependency 'shindo', '~> 0.3'
|
|
29
30
|
|
|
30
31
|
spec.add_dependency 'fog-core', '~> 2.1'
|
data/lib/fog/aws/compute.rb
CHANGED
|
@@ -233,21 +233,24 @@ module Fog
|
|
|
233
233
|
'fromPort' => -1,
|
|
234
234
|
'toPort' => -1,
|
|
235
235
|
'ipProtocol' => 'icmp',
|
|
236
|
-
'ipRanges' => []
|
|
236
|
+
'ipRanges' => [],
|
|
237
|
+
'ipv6Ranges' => []
|
|
237
238
|
},
|
|
238
239
|
{
|
|
239
240
|
'groups' => [{'groupName' => 'default', 'userId' => owner_id, 'groupId' => security_group_id}],
|
|
240
241
|
'fromPort' => 0,
|
|
241
242
|
'toPort' => 65535,
|
|
242
243
|
'ipProtocol' => 'tcp',
|
|
243
|
-
'ipRanges' => []
|
|
244
|
+
'ipRanges' => [],
|
|
245
|
+
'ipv6Ranges' => []
|
|
244
246
|
},
|
|
245
247
|
{
|
|
246
248
|
'groups' => [{'groupName' => 'default', 'userId' => owner_id, 'groupId' => security_group_id}],
|
|
247
249
|
'fromPort' => 0,
|
|
248
250
|
'toPort' => 65535,
|
|
249
251
|
'ipProtocol' => 'udp',
|
|
250
|
-
'ipRanges' => []
|
|
252
|
+
'ipRanges' => [],
|
|
253
|
+
'ipv6Ranges' => []
|
|
251
254
|
}
|
|
252
255
|
],
|
|
253
256
|
'ownerId' => owner_id
|
|
@@ -13,8 +13,6 @@ module Fog
|
|
|
13
13
|
|
|
14
14
|
CONTAINER_CREDENTIALS_HOST = "http://169.254.170.2"
|
|
15
15
|
|
|
16
|
-
STS_GLOBAL_ENDPOINT = "https://sts.amazonaws.com"
|
|
17
|
-
|
|
18
16
|
module ServiceMethods
|
|
19
17
|
def fetch_credentials(options)
|
|
20
18
|
if options[:use_iam_profile] && Fog.mocking?
|
|
@@ -23,7 +21,7 @@ module Fog
|
|
|
23
21
|
if options[:use_iam_profile]
|
|
24
22
|
begin
|
|
25
23
|
role_data = nil
|
|
26
|
-
region = options[:region]
|
|
24
|
+
region = options[:region] || ENV["AWS_DEFAULT_REGION"]
|
|
27
25
|
|
|
28
26
|
if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
|
29
27
|
connection = options[:connection] || Excon.new(CONTAINER_CREDENTIALS_HOST)
|
|
@@ -44,7 +42,15 @@ module Fog
|
|
|
44
42
|
:WebIdentityToken => File.read(options[:aws_web_identity_token_file] || ENV.fetch("AWS_WEB_IDENTITY_TOKEN_FILE")),
|
|
45
43
|
:Version => "2011-06-15",
|
|
46
44
|
}
|
|
47
|
-
|
|
45
|
+
|
|
46
|
+
sts_endpoint =
|
|
47
|
+
if ENV["AWS_STS_REGIONAL_ENDPOINTS"] == "regional" && region
|
|
48
|
+
"https://sts.#{region}.amazonaws.com"
|
|
49
|
+
else
|
|
50
|
+
"https://sts.amazonaws.com"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
connection = options[:connection] || Excon.new(sts_endpoint, :query => params)
|
|
48
54
|
document = Nokogiri::XML(connection.get(:idempotent => true, :expects => 200).body)
|
|
49
55
|
|
|
50
56
|
session = {
|
|
@@ -65,18 +71,19 @@ module Fog
|
|
|
65
71
|
role_name = connection.get(:path => INSTANCE_METADATA_PATH, :idempotent => true, :expects => 200, :headers => token_header).body
|
|
66
72
|
role_data = connection.get(:path => INSTANCE_METADATA_PATH+role_name, :idempotent => true, :expects => 200, :headers => token_header).body
|
|
67
73
|
session = Fog::JSON.decode(role_data)
|
|
68
|
-
|
|
74
|
+
|
|
69
75
|
region ||= connection.get(:path => INSTANCE_METADATA_AZ, :idempotent => true, :expects => 200, :headers => token_header).body[0..-2]
|
|
70
76
|
end
|
|
71
|
-
|
|
77
|
+
|
|
72
78
|
credentials = {}
|
|
73
79
|
credentials[:aws_access_key_id] = session['AccessKeyId']
|
|
74
80
|
credentials[:aws_secret_access_key] = session['SecretAccessKey']
|
|
75
81
|
credentials[:aws_session_token] = session['Token']
|
|
76
82
|
credentials[:aws_credentials_expire_at] = Time.xmlschema session['Expiration']
|
|
77
|
-
|
|
83
|
+
|
|
78
84
|
# set region by default to the one the instance is in.
|
|
79
85
|
credentials[:region] = region
|
|
86
|
+
credentials[:sts_endpoint] = sts_endpoint if sts_endpoint
|
|
80
87
|
#these indicate the metadata service is unavailable or has no profile setup
|
|
81
88
|
credentials
|
|
82
89
|
rescue Excon::Error => e
|
|
@@ -62,7 +62,8 @@ module Fog
|
|
|
62
62
|
# options::
|
|
63
63
|
# A hash that can contain any of the following keys:
|
|
64
64
|
# :cidr_ip (defaults to "0.0.0.0/0")
|
|
65
|
-
# :
|
|
65
|
+
# :cidr_ipv6 cannot be used with :cidr_ip
|
|
66
|
+
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip or :cidr_ipv6
|
|
66
67
|
# :ip_protocol (defaults to "tcp")
|
|
67
68
|
#
|
|
68
69
|
# == Returns:
|
|
@@ -178,7 +179,8 @@ module Fog
|
|
|
178
179
|
# options::
|
|
179
180
|
# A hash that can contain any of the following keys:
|
|
180
181
|
# :cidr_ip (defaults to "0.0.0.0/0")
|
|
181
|
-
# :
|
|
182
|
+
# :cidr_ipv6 cannot be used with :cidr_ip
|
|
183
|
+
# :group - ("account:group_name" or "account:group_id"), cannot be used with :cidr_ip or :cidr_ipv6
|
|
182
184
|
# :ip_protocol (defaults to "tcp")
|
|
183
185
|
#
|
|
184
186
|
# == Returns:
|
|
@@ -327,9 +329,15 @@ module Fog
|
|
|
327
329
|
}
|
|
328
330
|
|
|
329
331
|
if options[:group].nil?
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
332
|
+
if options[:cidr_ipv6].nil?
|
|
333
|
+
ip_permission['IpRanges'] = [
|
|
334
|
+
{ 'CidrIp' => options[:cidr_ip] || '0.0.0.0/0' }
|
|
335
|
+
]
|
|
336
|
+
else
|
|
337
|
+
ip_permission['Ipv6Ranges'] = [
|
|
338
|
+
{ 'CidrIpv6' => options[:cidr_ipv6] }
|
|
339
|
+
]
|
|
340
|
+
end
|
|
333
341
|
else
|
|
334
342
|
ip_permission['Groups'] = [
|
|
335
343
|
group_info(options[:group])
|
|
@@ -50,6 +50,7 @@ module Fog
|
|
|
50
50
|
attribute :subnet_id, :aliases => 'subnetId'
|
|
51
51
|
attribute :tenancy
|
|
52
52
|
attribute :tags, :aliases => 'tagSet'
|
|
53
|
+
attribute :tag_specifications, :aliases => 'tagSpecifications'
|
|
53
54
|
attribute :user_data
|
|
54
55
|
attribute :virtualization_type, :aliases => 'virtualizationType'
|
|
55
56
|
attribute :vpc_id, :aliases => 'vpcId'
|
|
@@ -166,6 +167,7 @@ module Fog
|
|
|
166
167
|
'SecurityGroupId' => security_group_ids,
|
|
167
168
|
'SubnetId' => subnet_id,
|
|
168
169
|
'UserData' => user_data,
|
|
170
|
+
'TagSpecifications' => tag_specifications,
|
|
169
171
|
}
|
|
170
172
|
options.delete_if {|key, value| value.nil?}
|
|
171
173
|
|
|
@@ -4,8 +4,11 @@ module Fog
|
|
|
4
4
|
module AWS
|
|
5
5
|
class Storage
|
|
6
6
|
class File < Fog::Model
|
|
7
|
-
MIN_MULTIPART_CHUNK_SIZE
|
|
8
|
-
|
|
7
|
+
# @deprecated use {Fog::AWS::Storage::MIN_MULTIPART_CHUNK_SIZE} instead
|
|
8
|
+
MIN_MULTIPART_CHUNK_SIZE = Fog::AWS::Storage::MIN_MULTIPART_CHUNK_SIZE
|
|
9
|
+
# @deprecated use {Fog::AWS::Storage::MAX_SINGLE_PUT_SIZE} instead
|
|
10
|
+
MAX_SINGLE_PUT_SIZE = Fog::AWS::Storage::MAX_SINGLE_PUT_SIZE
|
|
11
|
+
# @deprecated not used for anything
|
|
9
12
|
MULTIPART_COPY_THRESHOLD = 15728640
|
|
10
13
|
|
|
11
14
|
# @see AWS Object docs http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectOps.html
|
|
@@ -30,6 +33,7 @@ module Fog
|
|
|
30
33
|
attribute :version, :aliases => 'x-amz-version-id'
|
|
31
34
|
attribute :kms_key_id, :aliases => 'x-amz-server-side-encryption-aws-kms-key-id'
|
|
32
35
|
attribute :tags, :aliases => 'x-amz-tagging'
|
|
36
|
+
attribute :website_redirect_location, :aliases => 'x-amz-website-redirect-location'
|
|
33
37
|
|
|
34
38
|
UploadPartData = Struct.new(:part_number, :upload_options, :etag)
|
|
35
39
|
|
|
@@ -64,7 +68,7 @@ module Fog
|
|
|
64
68
|
# Use small chunk sizes to minimize memory. E.g. 5242880 = 5mb
|
|
65
69
|
attr_reader :multipart_chunk_size
|
|
66
70
|
def multipart_chunk_size=(mp_chunk_size)
|
|
67
|
-
|
|
71
|
+
service.validate_chunk_size(mp_chunk_size, 'multipart_chunk_size')
|
|
68
72
|
@multipart_chunk_size = mp_chunk_size
|
|
69
73
|
end
|
|
70
74
|
|
|
@@ -144,10 +148,9 @@ module Fog
|
|
|
144
148
|
def copy(target_directory_key, target_file_key, options = {})
|
|
145
149
|
requires :directory, :key
|
|
146
150
|
|
|
147
|
-
|
|
148
|
-
self.multipart_chunk_size = MIN_MULTIPART_CHUNK_SIZE * 2 if !multipart_chunk_size && self.content_length.to_i > MAX_SINGLE_PUT_SIZE
|
|
151
|
+
self.multipart_chunk_size = service.max_copy_chunk_size if multipart_chunk_size.nil?
|
|
149
152
|
|
|
150
|
-
if multipart_chunk_size && self.content_length.to_i >= multipart_chunk_size
|
|
153
|
+
if multipart_chunk_size > 0 && self.content_length.to_i >= multipart_chunk_size
|
|
151
154
|
upload_part_options = options.select { |key, _| ALLOWED_UPLOAD_PART_OPTIONS.include?(key.to_sym) }
|
|
152
155
|
upload_part_options = upload_part_options.merge({ 'x-amz-copy-source' => "#{directory.key}/#{key}" })
|
|
153
156
|
multipart_copy(options, upload_part_options, target_directory_key, target_file_key)
|
|
@@ -249,6 +252,7 @@ module Fog
|
|
|
249
252
|
# @option options [String] storage_class sets x-amz-storage-class HTTP header. Defaults to 'STANDARD'. Or, 'REDUCED_REDUNDANCY'
|
|
250
253
|
# @option options [String] encryption sets HTTP encryption header. Set to 'AES256' to encrypt files at rest on S3
|
|
251
254
|
# @option options [String] tags sets x-amz-tagging HTTP header. For example, 'Org-Id=1' or 'Org-Id=1&Service=MyService'
|
|
255
|
+
# @option options [String] website_redirect_location sets x-amz-website-redirect-location HTTP header. For example, 'website_redirect_location=http://www.rubydoc.info/github/fog/fog-aws'
|
|
252
256
|
# @return [Boolean] true if no errors
|
|
253
257
|
#
|
|
254
258
|
def save(options = {})
|
|
@@ -266,12 +270,11 @@ module Fog
|
|
|
266
270
|
options.merge!(metadata)
|
|
267
271
|
options['x-amz-storage-class'] = storage_class if storage_class
|
|
268
272
|
options['x-amz-tagging'] = tags if tags
|
|
273
|
+
options['x-amz-website-redirect-location'] = website_redirect_location if website_redirect_location
|
|
269
274
|
options.merge!(encryption_headers)
|
|
270
275
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
if multipart_chunk_size && Fog::Storage.get_body_size(body) >= multipart_chunk_size && body.respond_to?(:read)
|
|
276
|
+
self.multipart_chunk_size = service.max_put_chunk_size if multipart_chunk_size.nil?
|
|
277
|
+
if multipart_chunk_size > 0 && Fog::Storage.get_body_size(body) >= multipart_chunk_size && body.respond_to?(:read)
|
|
275
278
|
data = multipart_save(options)
|
|
276
279
|
merge_attributes(data.body)
|
|
277
280
|
else
|
|
@@ -5,9 +5,10 @@ module Fog
|
|
|
5
5
|
class DescribeSecurityGroups < Fog::Parsers::Base
|
|
6
6
|
def reset
|
|
7
7
|
@group = {}
|
|
8
|
-
@ip_permission = { 'groups' => [], 'ipRanges' => []}
|
|
9
|
-
@ip_permission_egress = { 'groups' => [], 'ipRanges' => []}
|
|
8
|
+
@ip_permission = { 'groups' => [], 'ipRanges' => [], 'ipv6Ranges' => []}
|
|
9
|
+
@ip_permission_egress = { 'groups' => [], 'ipRanges' => [], 'ipv6Ranges' => []}
|
|
10
10
|
@ip_range = {}
|
|
11
|
+
@ipv6_range = {}
|
|
11
12
|
@security_group = { 'ipPermissions' => [], 'ipPermissionsEgress' => [], 'tagSet' => {} }
|
|
12
13
|
@response = { 'securityGroupInfo' => [] }
|
|
13
14
|
@tag = {}
|
|
@@ -24,6 +25,8 @@ module Fog
|
|
|
24
25
|
@in_ip_permissions_egress = true
|
|
25
26
|
when 'ipRanges'
|
|
26
27
|
@in_ip_ranges = true
|
|
28
|
+
when 'ipv6Ranges'
|
|
29
|
+
@in_ipv6_ranges = true
|
|
27
30
|
when 'tagSet'
|
|
28
31
|
@in_tag_set = true
|
|
29
32
|
end
|
|
@@ -44,6 +47,8 @@ module Fog
|
|
|
44
47
|
case name
|
|
45
48
|
when 'cidrIp'
|
|
46
49
|
@ip_range[name] = value
|
|
50
|
+
when 'cidrIpv6'
|
|
51
|
+
@ipv6_range[name] = value
|
|
47
52
|
when 'fromPort', 'toPort'
|
|
48
53
|
if @in_ip_permissions_egress
|
|
49
54
|
@ip_permission_egress[name] = value.to_i
|
|
@@ -72,6 +77,8 @@ module Fog
|
|
|
72
77
|
end
|
|
73
78
|
when 'ipRanges'
|
|
74
79
|
@in_ip_ranges = false
|
|
80
|
+
when 'ipv6Ranges'
|
|
81
|
+
@in_ipv6_ranges = false
|
|
75
82
|
when 'item'
|
|
76
83
|
if @in_groups
|
|
77
84
|
if @in_ip_permissions_egress
|
|
@@ -87,12 +94,19 @@ module Fog
|
|
|
87
94
|
@ip_permission['ipRanges'] << @ip_range
|
|
88
95
|
end
|
|
89
96
|
@ip_range = {}
|
|
97
|
+
elsif @in_ipv6_ranges
|
|
98
|
+
if @in_ip_permissions_egress
|
|
99
|
+
@ip_permission_egress['ipv6Ranges'] << @ipv6_range
|
|
100
|
+
else
|
|
101
|
+
@ip_permission['ipv6Ranges'] << @ipv6_range
|
|
102
|
+
end
|
|
103
|
+
@ipv6_range = {}
|
|
90
104
|
elsif @in_ip_permissions
|
|
91
105
|
@security_group['ipPermissions'] << @ip_permission
|
|
92
|
-
@ip_permission = { 'groups' => [], 'ipRanges' => []}
|
|
106
|
+
@ip_permission = { 'groups' => [], 'ipRanges' => [], 'ipv6Ranges' => []}
|
|
93
107
|
elsif @in_ip_permissions_egress
|
|
94
108
|
@security_group['ipPermissionsEgress'] << @ip_permission_egress
|
|
95
|
-
@ip_permission_egress = { 'groups' => [], 'ipRanges' => []}
|
|
109
|
+
@ip_permission_egress = { 'groups' => [], 'ipRanges' => [], 'ipv6Ranges' => []}
|
|
96
110
|
else
|
|
97
111
|
@response['securityGroupInfo'] << @security_group
|
|
98
112
|
@security_group = { 'ipPermissions' => [], 'ipPermissionsEgress' => [], 'tagSet' => {} }
|
|
@@ -30,6 +30,9 @@ module Fog
|
|
|
30
30
|
# * 'IpRanges'<~Array>:
|
|
31
31
|
# * ip_range<~Hash>:
|
|
32
32
|
# * 'CidrIp'<~String> - CIDR range
|
|
33
|
+
# * 'Ipv6Ranges'<~Array>:
|
|
34
|
+
# * ip_range<~Hash>:
|
|
35
|
+
# * 'CidrIpv6'<~String> - CIDR range
|
|
33
36
|
# * 'ToPort'<~Integer> - End of port range (or -1 for ICMP wildcard)
|
|
34
37
|
#
|
|
35
38
|
# === Returns
|
|
@@ -72,6 +75,10 @@ module Fog
|
|
|
72
75
|
range_index += 1
|
|
73
76
|
params[format('IpPermissions.%d.IpRanges.%d.CidrIp', key_index, range_index)] = ip_range['CidrIp']
|
|
74
77
|
end
|
|
78
|
+
(permission['Ipv6Ranges'] || []).each_with_index do |ip_range, range_index|
|
|
79
|
+
range_index += 1
|
|
80
|
+
params[format('IpPermissions.%d.Ipv6Ranges.%d.CidrIpv6', key_index, range_index)] = ip_range['CidrIpv6']
|
|
81
|
+
end
|
|
75
82
|
end
|
|
76
83
|
params.reject {|k, v| v.nil? }
|
|
77
84
|
end
|
|
@@ -186,6 +193,14 @@ module Fog
|
|
|
186
193
|
'groups' => [],
|
|
187
194
|
'ipRanges' => [{'cidrIp' => options['CidrIp']}]
|
|
188
195
|
}
|
|
196
|
+
elsif options['CidrIpv6']
|
|
197
|
+
normalized_permissions << {
|
|
198
|
+
'ipProtocol' => options['IpProtocol'],
|
|
199
|
+
'fromPort' => Integer(options['FromPort']),
|
|
200
|
+
'toPort' => Integer(options['ToPort']),
|
|
201
|
+
'groups' => [],
|
|
202
|
+
'ipv6Ranges' => [{'cidrIpv6' => options['CidrIpv6']}]
|
|
203
|
+
}
|
|
189
204
|
elsif options['IpPermissions']
|
|
190
205
|
options['IpPermissions'].each do |permission|
|
|
191
206
|
|
|
@@ -27,6 +27,8 @@ module Fog
|
|
|
27
27
|
# * 'ipProtocol'<~String> - Ip protocol, must be in ['tcp', 'udp', 'icmp']
|
|
28
28
|
# * 'ipRanges'<~Array>:
|
|
29
29
|
# * 'cidrIp'<~String> - CIDR range
|
|
30
|
+
# * 'ipv6Ranges'<~Array>:
|
|
31
|
+
# * 'cidrIpv6'<~String> - CIDR ipv6 range
|
|
30
32
|
# * 'toPort'<~Integer> - End of port range (or -1 for ICMP wildcard)
|
|
31
33
|
# * 'ownerId'<~String> - AWS Access Key Id of the owner of the security group
|
|
32
34
|
# * 'NextToken'<~String> - The token to retrieve the next page of results
|
|
@@ -44,6 +44,11 @@ module Fog
|
|
|
44
44
|
# * 'PrivateIpAddresses.Primary'<~Bool> - Indicates whether the private IP address is the primary private IP address.
|
|
45
45
|
# * 'SecondaryPrivateIpAddressCount'<~Bool> - The number of private IP addresses to assign to the network interface.
|
|
46
46
|
# * 'AssociatePublicIpAddress'<~String> - Indicates whether to assign a public IP address to an instance in a VPC. The public IP address is assigned to a specific network interface
|
|
47
|
+
# * 'TagSpecifications'<~Array>: array of hashes
|
|
48
|
+
# * 'ResourceType'<~String> - Type of resource to apply tags on, e.g: instance or volume
|
|
49
|
+
# * 'Tags'<~Array> - List of hashs reprensenting tag to be set
|
|
50
|
+
# * 'Key'<~String> - Tag name
|
|
51
|
+
# * 'Value'<~String> - Tag value
|
|
47
52
|
# * 'ClientToken'<~String> - unique case-sensitive token for ensuring idempotency
|
|
48
53
|
# * 'DisableApiTermination'<~Boolean> - specifies whether or not to allow termination of the instance from the api
|
|
49
54
|
# * 'SecurityGroup'<~Array> or <~String> - Name of security group(s) for instances (not supported for VPC)
|
|
@@ -144,6 +149,45 @@ module Fog
|
|
|
144
149
|
end
|
|
145
150
|
end
|
|
146
151
|
end
|
|
152
|
+
if tag_specifications = options.delete('TagSpecifications')
|
|
153
|
+
# From https://docs.aws.amazon.com/sdk-for-ruby/v2/api/Aws/EC2/Client.html#run_instances-instance_method
|
|
154
|
+
# And https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html
|
|
155
|
+
# Discussed at https://github.com/fog/fog-aws/issues/603
|
|
156
|
+
#
|
|
157
|
+
# Example
|
|
158
|
+
#
|
|
159
|
+
# TagSpecifications: [
|
|
160
|
+
# {
|
|
161
|
+
# ResourceType: "instance",
|
|
162
|
+
# Tags: [
|
|
163
|
+
# {
|
|
164
|
+
# Key: "Project",
|
|
165
|
+
# Value: "MyProject",
|
|
166
|
+
# },
|
|
167
|
+
# ],
|
|
168
|
+
# },
|
|
169
|
+
# {
|
|
170
|
+
# ResourceType: "volume",
|
|
171
|
+
# Tags: [
|
|
172
|
+
# {
|
|
173
|
+
# Key: "Project",
|
|
174
|
+
# Value: "MyProject",
|
|
175
|
+
# },
|
|
176
|
+
# ],
|
|
177
|
+
# },
|
|
178
|
+
# ]
|
|
179
|
+
tag_specifications.each_with_index do |val, idx|
|
|
180
|
+
resource_type = val["ResourceType"]
|
|
181
|
+
tags = val["Tags"]
|
|
182
|
+
options["TagSpecification.#{idx}.ResourceType"] = resource_type
|
|
183
|
+
tags.each_with_index do |tag, tag_idx|
|
|
184
|
+
aws_tag_key = "TagSpecification.#{idx}.Tag.#{tag_idx}.Key"
|
|
185
|
+
aws_tag_value = "TagSpecification.#{idx}.Tag.#{tag_idx}.Value"
|
|
186
|
+
options[aws_tag_key] = tag["Key"]
|
|
187
|
+
options[aws_tag_value] = tag["Value"]
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
147
191
|
|
|
148
192
|
idempotent = !(options['ClientToken'].nil? || options['ClientToken'].empty?)
|
|
149
193
|
|
|
@@ -36,13 +36,20 @@ module Fog
|
|
|
36
36
|
data << "<Quiet>true</Quiet>" if headers.delete(:quiet)
|
|
37
37
|
version_ids = headers.delete('versionId')
|
|
38
38
|
object_names.each do |object_name|
|
|
39
|
-
data << "<Object>"
|
|
40
|
-
data << "<Key>#{CGI.escapeHTML(object_name)}</Key>"
|
|
41
39
|
object_version = version_ids.nil? ? nil : version_ids[object_name]
|
|
42
40
|
if object_version
|
|
43
|
-
|
|
41
|
+
object_version = object_version.is_a?(String) ? [object_version] : object_version
|
|
42
|
+
object_version.each do |version_id|
|
|
43
|
+
data << "<Object>"
|
|
44
|
+
data << "<Key>#{CGI.escapeHTML(object_name)}</Key>"
|
|
45
|
+
data << "<VersionId>#{CGI.escapeHTML(version_id)}</VersionId>"
|
|
46
|
+
data << "</Object>"
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
data << "<Object>"
|
|
50
|
+
data << "<Key>#{CGI.escapeHTML(object_name)}</Key>"
|
|
51
|
+
data << "</Object>"
|
|
44
52
|
end
|
|
45
|
-
data << "</Object>"
|
|
46
53
|
end
|
|
47
54
|
data << "</Delete>"
|
|
48
55
|
|
|
@@ -72,10 +79,13 @@ module Fog
|
|
|
72
79
|
response.body = { 'DeleteResult' => [] }
|
|
73
80
|
version_ids = headers.delete('versionId')
|
|
74
81
|
object_names.each do |object_name|
|
|
75
|
-
object_version = version_ids.nil? ? nil : version_ids[object_name]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
82
|
+
object_version = version_ids.nil? ? [nil] : version_ids[object_name]
|
|
83
|
+
object_version = object_version.is_a?(String) ? [object_version] : object_version
|
|
84
|
+
object_version.each do |version_id|
|
|
85
|
+
response.body['DeleteResult'] << delete_object_helper(bucket,
|
|
86
|
+
object_name,
|
|
87
|
+
version_id)
|
|
88
|
+
end
|
|
79
89
|
end
|
|
80
90
|
else
|
|
81
91
|
response.status = 404
|