fog-aws 3.3.0 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +10 -12
  3. data/fog-aws.gemspec +1 -1
  4. data/lib/fog/aws/compute.rb +2 -0
  5. data/lib/fog/aws/models/compute/address.rb +1 -0
  6. data/lib/fog/aws/models/compute/flavors.rb +440 -0
  7. data/lib/fog/aws/models/rds/cluster.rb +9 -1
  8. data/lib/fog/aws/models/rds/server.rb +3 -3
  9. data/lib/fog/aws/models/storage/directory.rb +35 -0
  10. data/lib/fog/aws/parsers/compute/describe_addresses.rb +30 -9
  11. data/lib/fog/aws/parsers/compute/describe_image_attribute.rb +122 -0
  12. data/lib/fog/aws/parsers/compute/describe_security_groups.rb +1 -1
  13. data/lib/fog/aws/requests/compute/describe_image_attribute.rb +74 -0
  14. data/lib/fog/aws/requests/compute/describe_security_groups.rb +12 -1
  15. data/lib/fog/aws/requests/compute/modify_instance_placement.rb +33 -0
  16. data/lib/fog/aws/requests/dns/change_resource_record_sets.rb +1 -1
  17. data/lib/fog/aws/requests/dynamodb/update_item.rb +6 -5
  18. data/lib/fog/aws/requests/storage/get_bucket_location.rb +2 -3
  19. data/lib/fog/aws/requests/storage/get_service.rb +2 -2
  20. data/lib/fog/aws/requests/storage/put_object.rb +5 -3
  21. data/lib/fog/aws/storage.rb +9 -2
  22. data/lib/fog/aws/version.rb +1 -1
  23. data/tests/credentials_tests.rb +38 -37
  24. data/tests/helper.rb +2 -2
  25. data/tests/helpers/collection_helper.rb +3 -4
  26. data/tests/helpers/compute/flavors_helper.rb +1 -5
  27. data/tests/helpers/compute/server_helper.rb +1 -3
  28. data/tests/helpers/compute/servers_helper.rb +0 -2
  29. data/tests/helpers/dns_helper.rb +32 -31
  30. data/tests/helpers/formats_helper.rb +58 -56
  31. data/tests/helpers/formats_helper_tests.rb +22 -25
  32. data/tests/helpers/mock_helper.rb +96 -96
  33. data/tests/helpers/model_helper.rb +4 -5
  34. data/tests/helpers/responds_to_helper.rb +1 -1
  35. data/tests/helpers/schema_validator_tests.rb +21 -24
  36. data/tests/helpers/succeeds_helper.rb +1 -1
  37. data/tests/parsers/compute/describe_images_tests.rb +1 -1
  38. data/tests/parsers/elb/describe_load_balancers.rb +1 -1
  39. data/tests/requests/compute/image_tests.rb +9 -0
  40. data/tests/requests/sts/assume_role_with_web_identity_tests.rb +2 -0
  41. data/tests/signaturev4_tests.rb +21 -22
  42. data/tests/signed_params_tests.rb +7 -7
  43. data/tests/storage_tests.rb +1 -1
  44. metadata +8 -6
@@ -23,7 +23,15 @@ module Fog
23
23
  attr_accessor :storage_encrypted #not in the response
24
24
 
25
25
  def ready?
26
- state == "available"
26
+ # [2019.01] I don't think this is going to work, at least not with Aurora
27
+ # clusters. In my testing, the state reported by Fog for an Aurora cluster
28
+ # is "active" as soon as the cluster is retrievable from AWS, and the
29
+ # value doesn't change after that. Contrast that with the AWS Console UI,
30
+ # which reports the cluster as "Creating" while it's being created. I don't
31
+ # know where Fog is getting the state value from, but I don't think it's
32
+ # correct, at least not for the purpose of knowing if the Cluster is ready
33
+ # to have individual instances added to it.
34
+ state == 'available' || state == 'active'
27
35
  end
28
36
 
29
37
  def snapshots
@@ -118,14 +118,14 @@ module Fog
118
118
  else
119
119
  requires :engine
120
120
 
121
- if engine == 'aurora'
121
+ if engine.start_with?('aurora')
122
122
  requires :cluster_id
123
- self.flavor_id ||= 'db.r3.large'
123
+ self.flavor_id ||= 'db.r4.large'
124
124
  else
125
125
  requires :master_username
126
126
  requires :password
127
127
  requires :allocated_storage
128
- self.flavor_id ||= 'db.m1.small'
128
+ self.flavor_id ||= 'db.m4.large'
129
129
  end
130
130
 
131
131
  data = service.create_db_instance(id, attributes_to_params)
@@ -30,6 +30,30 @@ module Fog
30
30
  false
31
31
  end
32
32
 
33
+ # @param options [Hash] (defaults to: {}) — a customizable set of options.
34
+ # Consider tuning this values for big buckets.
35
+ # @option options timeout [Integer] — default: Fog.timeout — Maximum number of
36
+ # seconds to wait for the bucket to be empty.
37
+ # @option options interval [Proc|Integer] — default: Fog.interval — Seconds to wait before
38
+ # retrying to check if the bucket is empty.
39
+ def destroy!(options = {})
40
+ requires :key
41
+ options = {
42
+ timeout: Fog.timeout,
43
+ interval: Fog.interval,
44
+ }.merge(options)
45
+
46
+ attempts = 0
47
+ begin
48
+ clear!
49
+ Fog.wait_for(options[:timeout], options[:interval]) { objects_keys.size == 0 }
50
+ service.delete_bucket(key)
51
+ true
52
+ rescue Excon::Errors::HTTPStatusError
53
+ false
54
+ end
55
+ end
56
+
33
57
  def location
34
58
  @location ||= (bucket_location || Storage::DEFAULT_REGION)
35
59
  end
@@ -119,6 +143,17 @@ module Fog
119
143
  data = service.get_bucket_location(key)
120
144
  data.body['LocationConstraint']
121
145
  end
146
+
147
+ def objects_keys
148
+ requires :key
149
+ bucket_query = service.get_bucket(key)
150
+ bucket_query.body["Contents"].map {|c| c["Key"]}
151
+ end
152
+
153
+ def clear!
154
+ requires :key
155
+ service.delete_multiple_objects(key, objects_keys) if objects_keys.size > 0
156
+ end
122
157
  end
123
158
  end
124
159
  end
@@ -4,19 +4,40 @@ module Fog
4
4
  module Compute
5
5
  class DescribeAddresses < Fog::Parsers::Base
6
6
  def reset
7
- @address = {}
8
7
  @response = { 'addressesSet' => [] }
8
+ @address = {'tagSet' => {}}
9
+ @tag = {}
10
+ end
11
+
12
+ def start_element(name, attrs = [])
13
+ super
14
+ if name == 'tagSet'
15
+ @in_tag_set = true
16
+ end
9
17
  end
10
18
 
11
19
  def end_element(name)
12
- case name
13
- when 'instanceId', 'publicIp', 'domain', 'allocationId', 'associationId', 'networkInterfaceId', 'networkInterfaceOwnerId', 'privateIpAddress'
14
- @address[name] = value
15
- when 'item'
16
- @response['addressesSet'] << @address
17
- @address = {}
18
- when 'requestId'
19
- @response[name] = value
20
+ if @in_tag_set
21
+ case name
22
+ when 'item'
23
+ @address['tagSet'][@tag['key']] = @tag['value']
24
+ @tag = {}
25
+ when 'key', 'value'
26
+ @tag[name] = value
27
+ when 'tagSet'
28
+ @in_tag_set = false
29
+ end
30
+ else
31
+ case name
32
+ when 'instanceId', 'publicIp', 'domain', 'allocationId', 'associationId', 'networkInterfaceId', 'networkInterfaceOwnerId', 'privateIpAddress'
33
+ @address[name] = value
34
+ when 'item'
35
+ @response['addressesSet'] << @address
36
+ @address = { 'tagSet' => {} }
37
+ when 'requestId'
38
+ @response[name] = value
39
+ end
40
+
20
41
  end
21
42
  end
22
43
  end
@@ -0,0 +1,122 @@
1
+ module Fog
2
+ module Parsers
3
+ module AWS
4
+ module Compute
5
+ class DescribeImageAttribute < Fog::Parsers::Base
6
+ def reset
7
+ @response = { }
8
+ @in_description = false
9
+ @in_kernelId = false
10
+ @in_ramdiskId = false
11
+ @in_launchPermission = false
12
+ @in_productCodes = false
13
+ @in_blockDeviceMapping = false
14
+ @in_sriovNetSupport = false
15
+ end
16
+
17
+ def start_element(name, attrs = [])
18
+ super
19
+ case name
20
+ when 'description'
21
+ @in_description = true
22
+ when 'kernel'
23
+ @in_kernel = true
24
+ when 'ramdisk'
25
+ @in_ramdisk = true
26
+ when 'launchPermission'
27
+ @in_launchPermission= true
28
+ unless @response.key?('launchPermission')
29
+ @response['launchPermission'] = []
30
+ end
31
+ when 'productCodes'
32
+ @in_productCodes = true
33
+ @product_codes = {}
34
+ unless @response.key?('productCodes')
35
+ @response['productCodes'] = []
36
+ end
37
+ when 'blockDeviceMapping'
38
+ @in_blockDeviceMapping = true
39
+ @block_device_mapping = {}
40
+ unless @response.key?('blockDeviceMapping')
41
+ @response['blockDeviceMapping'] = []
42
+ end
43
+ when 'sriovNetSupport'
44
+ unless @response.key?('sriovNetSupport')
45
+ @response['sriovNetSupport'] = 'false'
46
+ end
47
+ @in_sriovNetSupport = true
48
+ end
49
+ end
50
+
51
+ def end_element(name)
52
+ if @in_description
53
+ case name
54
+ when 'value'
55
+ @response['description'] = value
56
+ when 'description'
57
+ @in_description= false
58
+ end
59
+ elsif @in_kernel
60
+ case name
61
+ when 'value'
62
+ @response['kernelId'] = value
63
+ when 'kernel'
64
+ @in_kernelId = false
65
+ end
66
+ elsif @in_ramdisk
67
+ case name
68
+ when 'value'
69
+ @response['ramdiskId'] = value
70
+ when 'ramdisk'
71
+ @in_ramdiskId = false
72
+ end
73
+ elsif @in_launchPermission
74
+ case name
75
+ when 'group', 'userId'
76
+ @response['launchPermission'] << value
77
+ when 'launchPermission'
78
+ @in_launchPermission = false
79
+ end
80
+ elsif @in_blockDeviceMapping
81
+ case name
82
+ when 'item'
83
+ @response["blockDeviceMapping"] << @block_device_mapping
84
+ @block_device_mapping = {}
85
+ when 'volumeId', 'status', 'deviceName'
86
+ @block_device_mapping[name] = value
87
+ when 'attachTime'
88
+ @block_device_mapping['attachTime'] = Time.parse(value)
89
+ when 'deleteOnTermination'
90
+ @block_device_mapping['deleteOnTermination'] = (value == 'true')
91
+ when 'blockDeviceMapping'
92
+ @in_blockDeviceMapping = false
93
+ end
94
+ elsif @in_productCodes
95
+ case name
96
+ when 'item'
97
+ @response['productCodes'] << @product_codes
98
+ @product_codes = {}
99
+ when 'productCode', 'type'
100
+ @product_codes[name] = value
101
+ when 'productCodes'
102
+ @in_productCodes = false
103
+ end
104
+ elsif @in_sriovNetSupport
105
+ case name
106
+ when 'value'
107
+ @response["sriovNetSupport"] = value
108
+ when "sriovNetSupport"
109
+ @in_sriovNetSupport = false
110
+ end
111
+ else
112
+ case name
113
+ when 'requestId', 'imageId'
114
+ @response[name] = value
115
+ end
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -97,7 +97,7 @@ module Fog
97
97
  @response['securityGroupInfo'] << @security_group
98
98
  @security_group = { 'ipPermissions' => [], 'ipPermissionsEgress' => [], 'tagSet' => {} }
99
99
  end
100
- when 'requestId'
100
+ when 'requestId', 'nextToken'
101
101
  @response[name] = value
102
102
  when 'userId'
103
103
  @group[name] = value
@@ -0,0 +1,74 @@
1
+ module Fog
2
+ module AWS
3
+ class Compute
4
+ class Real
5
+ require 'fog/aws/parsers/compute/describe_image_attribute'
6
+ # Describes an image attribute value
7
+ #
8
+ # ==== Parameters
9
+ # * image_id<~String> - The ID of the image you want to describe an attribute of
10
+ # * attribute<~String> - The attribute to describe, must be one of the following:
11
+ # -'description'
12
+ # -'kernel'
13
+ # -'ramdisk'
14
+ # -'launchPermission'
15
+ # -'productCodes'
16
+ # -'blockDeviceMapping'
17
+ # -'sriovNetSupport'
18
+ #
19
+ # === Returns
20
+ # * response<~Excon::Response>:
21
+ # * body<~Hash>:
22
+ # * 'requestId'<~String> - Id of request
23
+ # * 'description'<~String> - The description for the AMI
24
+ # * 'imageId'<~String> - The ID of the image
25
+ # * 'kernelId'<~String> - The kernel ID
26
+ # * 'ramdiskId'<~String> - The RAM disk ID
27
+ # * 'blockDeviceMapping'<~List> - The block device mapping of the image
28
+ # * 'productCodes'<~List> - A list of product codes
29
+ # * 'sriovNetSupport'<~String> - The value to use for a resource attribute
30
+ # (Amazon API Reference)[http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeImageAttribute.html]
31
+ def describe_image_attribute(image_id, attribute)
32
+ request(
33
+ 'Action' => 'DescribeImageAttribute',
34
+ 'ImageId' => image_id,
35
+ 'Attribute' => attribute,
36
+ :parser => Fog::Parsers::AWS::Compute::DescribeImageAttribute.new
37
+ )
38
+ end
39
+ end
40
+
41
+ class Mock
42
+ def describe_image_attribute(image_id, attribute)
43
+ response = Excon::Response.new
44
+ if image = self.data[:images].values.find{ |i| i['imageId'] == image_id }
45
+ response.status = 200
46
+ response.body = {
47
+ 'requestId' => Fog::AWS::Mock.request_id,
48
+ 'imageId' => image_id
49
+ }
50
+ case attribute
51
+ when 'kernel'
52
+ response.body[attribute] = image["kernelId"]
53
+ when 'ramdisk'
54
+ response.body[attribute] = image["ramdiskId"]
55
+ when 'sriovNetSupport'
56
+ response.body[attribute] = 'simple'
57
+ when 'launchPermission'
58
+ if image_launch_permissions = self.data[:image_launch_permissions][image_id]
59
+ response.body[attribute] = image_launch_permissions[:users]
60
+ else
61
+ response.body[attribute] = []
62
+ end
63
+ else
64
+ response.body[attribute] = image[attribute]
65
+ end
66
+ response
67
+ else
68
+ raise Fog::AWS::Compute::NotFound.new("The Image '#{image_id}' does not exist")
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -8,6 +8,8 @@ module Fog
8
8
  #
9
9
  # ==== Parameters
10
10
  # * filters<~Hash> - List of filters to limit results with
11
+ # * 'MaxResults'<~Integer> - The maximum number of results to return for the request in a single page
12
+ # * 'NextToken'<~String> - The token to retrieve the next page of results
11
13
  #
12
14
  # === Returns
13
15
  # * response<~Excon::Response>:
@@ -27,6 +29,7 @@ module Fog
27
29
  # * 'cidrIp'<~String> - CIDR range
28
30
  # * 'toPort'<~Integer> - End of port range (or -1 for ICMP wildcard)
29
31
  # * 'ownerId'<~String> - AWS Access Key Id of the owner of the security group
32
+ # * 'NextToken'<~String> - The token to retrieve the next page of results
30
33
  #
31
34
  # {Amazon API Reference}[http://docs.amazonwebservices.com/AWSEC2/latest/APIReference/ApiReference-query-DescribeSecurityGroups.html]
32
35
  def describe_security_groups(filters = {})
@@ -34,7 +37,15 @@ module Fog
34
37
  Fog::Logger.deprecation("describe_security_groups with #{filters.class} param is deprecated, use describe_security_groups('group-name' => []) instead [light_black](#{caller.first})[/]")
35
38
  filters = {'group-name' => [*filters]}
36
39
  end
37
- params = Fog::AWS.indexed_filters(filters)
40
+
41
+ options = {}
42
+ for key in %w[MaxResults NextToken]
43
+ if filters.is_a?(Hash) && filters.key?(key)
44
+ options[key] = filters.delete(key)
45
+ end
46
+ end
47
+
48
+ params = Fog::AWS.indexed_filters(filters).merge!(options)
38
49
  request({
39
50
  'Action' => 'DescribeSecurityGroups',
40
51
  :idempotent => true,
@@ -0,0 +1,33 @@
1
+ module Fog
2
+ module AWS
3
+ class Compute
4
+ class Real
5
+ require 'fog/aws/parsers/compute/basic'
6
+
7
+ # Modify instance placement
8
+ #
9
+ # ==== Parameters
10
+ # * instance_id<~String> - Id of instance to modify
11
+ # * attributes<~Hash>:
12
+ # 'Affinity.Value'<~String> - The affinity setting for the instance, in ['default', 'host']
13
+ # 'GroupName.Value'<~String> - The name of the placement group in which to place the instance
14
+ # 'HostId.Value'<~String> - The ID of the Dedicated Host with which to associate the instance
15
+ # 'Tenancy.Value'<~String> - The tenancy for the instance, in ['dedicated', 'host']
16
+ #
17
+ # {Amazon API Reference}[https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_ModifyInstancePlacement.html]
18
+ #
19
+ def modify_instance_placement(instance_id, attributes)
20
+ params = {}
21
+ params.merge!(attributes)
22
+ request({
23
+ 'Action' => 'ModifyInstancePlacement',
24
+ 'InstanceId' => instance_id,
25
+ :idempotent => true,
26
+ :parser => Fog::Parsers::AWS::Compute::Basic.new
27
+ }.merge!(params))
28
+ end
29
+
30
+ end
31
+ end
32
+ end
33
+ end
@@ -194,7 +194,7 @@ module Fog
194
194
  # change_resource_record_sets("ABCDEFGHIJKLMN", change_batch_options)
195
195
  #
196
196
  def change_resource_record_sets(zone_id, change_batch, options = {})
197
- body = AWS.change_resource_record_sets_data(zone_id, change_batch, @version, options)
197
+ body = Fog::AWS::DNS.change_resource_record_sets_data(zone_id, change_batch, @version, options)
198
198
  request({
199
199
  :body => body,
200
200
  :idempotent => true,
@@ -7,15 +7,15 @@ module Fog
7
7
  #
8
8
  # ==== Parameters
9
9
  # * 'table_name'<~String> - name of table for item
10
- # * 'key'<~Hash> - list of elements to be updated and their value
10
+ # * 'key'<~Hash> - list of Key attributes
11
11
  # {
12
12
  # "ForumName": {"S": "Amazon DynamoDB"},
13
13
  # "Subject": {"S": "Maximum number of items?"}
14
14
  # }
15
15
  #
16
16
  # * 'options'<~Hash>:
17
- # * 'KeyConditionExpression'<~String> - the condition elements need to match
18
- # * 'ExpressionAttributeValues'<~Hash> - values to be used in the key condition expression
17
+ # * 'UpdateExpression'<~String> - the expression that will update the item
18
+ # * 'ExpressionAttributeValues'<~Hash> - values to be used in the update expression
19
19
  # * 'ReturnValues'<~String> - data to return in %w{ALL_NEW ALL_OLD NONE UPDATED_NEW UPDATED_OLD}, defaults to NONE
20
20
  #
21
21
  # ==== Returns
@@ -29,13 +29,14 @@ module Fog
29
29
  if deprecated_attribute_updates
30
30
  raise DeprecatedAttributeUpdates, "The `20111205` DynamoDB API is deprecated. You need to use `ExpressionAttributeValues` instead of `AttributeUpdates`."
31
31
  attribute_updates = options
32
- options = deprecated_attribute_updates
32
+ options = deprecated_attribute_updates.merge(
33
+ 'AttributeUpdates' => attribute_updates,
34
+ )
33
35
  end
34
36
 
35
37
  body = {
36
38
  'Key' => key,
37
39
  'TableName' => table_name,
38
- 'AttributeUpdates' => attribute_updates,
39
40
  }.merge(options)
40
41
 
41
42
  request(