fog-aws 0.1.2 → 0.2.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.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -2
  3. data/lib/fog/aws.rb +29 -27
  4. data/lib/fog/aws/elb.rb +0 -1
  5. data/lib/fog/aws/iam.rb +4 -2
  6. data/lib/fog/aws/kms.rb +180 -0
  7. data/lib/fog/aws/mock.rb +13 -1
  8. data/lib/fog/aws/models/compute/flavors.rb +40 -0
  9. data/lib/fog/aws/models/elasticache/cluster.rb +1 -0
  10. data/lib/fog/aws/models/kms/key.rb +34 -0
  11. data/lib/fog/aws/models/kms/keys.rb +29 -0
  12. data/lib/fog/aws/models/rds/server.rb +33 -26
  13. data/lib/fog/aws/parsers/compute/describe_reserved_instances.rb +1 -1
  14. data/lib/fog/aws/parsers/elasticache/cache_cluster_parser.rb +15 -3
  15. data/lib/fog/aws/parsers/kms/describe_key.rb +34 -0
  16. data/lib/fog/aws/parsers/kms/list_keys.rb +38 -0
  17. data/lib/fog/aws/parsers/rds/db_parser.rb +7 -14
  18. data/lib/fog/aws/rds.rb +1 -1
  19. data/lib/fog/aws/requests/compute/describe_spot_price_history.rb +59 -0
  20. data/lib/fog/aws/requests/compute/request_spot_instances.rb +80 -0
  21. data/lib/fog/aws/requests/dns/change_resource_record_sets.rb +36 -5
  22. data/lib/fog/aws/requests/dns/list_resource_record_sets.rb +33 -5
  23. data/lib/fog/aws/requests/elb/create_load_balancer.rb +15 -2
  24. data/lib/fog/aws/requests/iam/create_role.rb +5 -5
  25. data/lib/fog/aws/requests/kms/create_key.rb +62 -0
  26. data/lib/fog/aws/requests/kms/describe_key.rb +27 -0
  27. data/lib/fog/aws/requests/kms/list_keys.rb +82 -0
  28. data/lib/fog/aws/requests/rds/create_db_instance.rb +33 -38
  29. data/lib/fog/aws/requests/rds/create_db_instance_read_replica.rb +7 -2
  30. data/lib/fog/aws/requests/rds/promote_read_replica.rb +7 -6
  31. data/lib/fog/aws/requests/sns/subscribe.rb +1 -1
  32. data/lib/fog/aws/storage.rb +6 -3
  33. data/lib/fog/aws/version.rb +1 -1
  34. data/tests/helper.rb +2 -2
  35. data/tests/models/rds/helper.rb +10 -3
  36. data/tests/models/rds/server_tests.rb +7 -4
  37. data/tests/requests/compute/spot_instance_tests.rb +2 -2
  38. data/tests/requests/compute/spot_price_history_tests.rb +0 -2
  39. data/tests/requests/kms/helper.rb +27 -0
  40. data/tests/requests/kms/key_tests.rb +23 -0
  41. data/tests/requests/rds/helper.rb +52 -46
  42. data/tests/requests/rds/instance_tests.rb +16 -12
  43. metadata +12 -2
@@ -151,6 +151,19 @@ module Fog
151
151
  end
152
152
 
153
153
  class Mock
154
+ SET_PREFIX = 'SET_'
155
+ def record_exist?(zone,change,change_name)
156
+ return false if zone[:records][change[:type]].nil?
157
+ current_records = zone[:records][change[:type]][change_name]
158
+ return false if current_records.nil?
159
+
160
+ if !change[:set_identifier].empty?
161
+ !current_records[change[:SetIdentifier]].nil?
162
+ else
163
+ !current_records.empty?
164
+ end
165
+ end
166
+
154
167
  def change_resource_record_sets(zone_id, change_batch, options = {})
155
168
  response = Excon::Response.new
156
169
  errors = []
@@ -171,9 +184,9 @@ module Fog
171
184
  zone[:records][change[:type]] = {}
172
185
  end
173
186
 
174
- if zone[:records][change[:type]][change_name].nil?
187
+ if !record_exist?(zone, change, change_name)
175
188
  # raise change.to_s if change[:resource_records].nil?
176
- zone[:records][change[:type]][change_name] =
189
+ new_record =
177
190
  if change[:alias_target]
178
191
  record = {
179
192
  :alias_target => change[:alias_target]
@@ -183,17 +196,35 @@ module Fog
183
196
  :ttl => change[:ttl].to_s,
184
197
  }
185
198
  end
186
- zone[:records][change[:type]][change_name] = {
199
+
200
+ new_record = {
187
201
  :change_id => change_id,
188
202
  :resource_records => change[:resource_records] || [],
189
203
  :name => change_name,
190
- :type => change[:type]
204
+ :type => change[:type],
205
+ :set_identifier => change[:set_identifier],
206
+ :weight => change[:weight]
191
207
  }.merge(record)
208
+
209
+ if change[:set_identifier].nil?
210
+ zone[:records][change[:type]][change_name] = new_record
211
+ else
212
+ zone[:records][change[:type]][change_name] = {} if zone[:records][change[:type]][change_name].nil?
213
+ zone[:records][change[:type]][change_name][SET_PREFIX + change[:set_identifier]] = new_record
214
+ end
192
215
  else
193
216
  errors << "Tried to create resource record set #{change[:name]}. type #{change[:type]}, but it already exists"
194
217
  end
195
218
  when "DELETE"
196
- if zone[:records][change[:type]].nil? || zone[:records][change[:type]].delete(change_name).nil?
219
+ action_performed = false
220
+ if !zone[:records][change[:type]].nil? && !zone[:records][change[:type]][change_name].nil? && !change[:set_identifier].nil?
221
+ action_performed = true unless zone[:records][change[:type]][change_name].delete(SET_PREFIX + change[:set_identifier]).nil?
222
+ zone[:records][change[:type]].delete(change_name) if zone[:records][change[:type]][change_name].empty?
223
+ elsif !zone[:records][change[:type]].nil?
224
+ action_performed = true unless zone[:records][change[:type]].delete(change_name).nil?
225
+ end
226
+
227
+ if !action_performed
197
228
  errors << "Tried to delete resource record set #{change[:name]}. type #{change[:type]}, but it was not found"
198
229
  end
199
230
  end
@@ -59,6 +59,22 @@ module Fog
59
59
  end
60
60
 
61
61
  class Mock
62
+ def list_all_records(record, zone, name)
63
+ [].tap do |tmp_records|
64
+ tmp_records.push(record) if !record[:name].nil? && ( name.nil? || record[:name].gsub(zone[:name],"") >= name)
65
+ record.each do |key,subr|
66
+ if subr.is_a?(Hash) && key.is_a?(String) &&
67
+ key.start_with?(Fog::DNS::AWS::Mock::SET_PREFIX)
68
+ if name.nil?
69
+ tmp_records.append(subr)
70
+ else
71
+ tmp_records.append(subr) if !subr[:name].nil? && subr[:name].gsub(zone[:name],"") >= name
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+
62
78
  def list_resource_record_sets(zone_id, options = {})
63
79
  maxitems = [options[:max_items]||100,100].min
64
80
 
@@ -76,13 +92,23 @@ module Fog
76
92
 
77
93
  records ||= []
78
94
 
79
- # sort for pagination
80
- records.sort! { |a,b| a[:name].gsub(zone[:name],"") <=> b[:name].gsub(zone[:name],"") }
81
-
95
+ tmp_records = []
82
96
  if options[:name]
83
97
  name = options[:name].gsub(zone[:name],"")
84
- records = records.select{|r| r[:name].gsub(zone[:name],"") >= name }
98
+
99
+ records.each do |r|
100
+ tmp_records += list_all_records(r, zone, name)
101
+ end
102
+ else
103
+ records.each do |r|
104
+ tmp_records += list_all_records(r, zone, nil)
105
+ end
85
106
  end
107
+ records = tmp_records
108
+
109
+ # sort for pagination
110
+ records.sort! { |a,b| a[:name].gsub(zone[:name],"") <=> b[:name].gsub(zone[:name],"") }
111
+
86
112
 
87
113
  next_record = records[maxitems]
88
114
  records = records[0, maxitems]
@@ -106,7 +132,9 @@ module Fog
106
132
  {
107
133
  'ResourceRecords' => r[:resource_records],
108
134
  'Name' => r[:name],
109
- 'Type' => r[:type]
135
+ 'Type' => r[:type],
136
+ 'SetIdentifier' => r[:set_identifier],
137
+ 'Weight' => r[:weight]
110
138
  }.merge(record)
111
139
  end,
112
140
  'MaxItems' => maxitems,
@@ -74,9 +74,22 @@ module Fog
74
74
  dns_name = Fog::AWS::ELB::Mock.dns_name(lb_name, @region)
75
75
 
76
76
  availability_zones = [*availability_zones].compact
77
- region = availability_zones.empty? ? "us-east-1" : availability_zones.first.gsub(/[a-z]$/, '')
78
- supported_platforms = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:account_attributes].find { |h| h["attributeName"] == "supported-platforms" }["values"]
79
77
  subnet_ids = options[:subnet_ids] || []
78
+ region = if availability_zones.any?
79
+ availability_zones.first.gsub(/[a-z]$/, '')
80
+ elsif subnet_ids.any?
81
+ # using Hash here for Rubt 1.8.7 support.
82
+ Hash[
83
+ Fog::Compute::AWS::Mock.data.select do |_, region_data|
84
+ region_data[@aws_access_key_id][:subnets].any? do |region_subnets|
85
+ subnet_ids.include? region_subnets['subnetId']
86
+ end
87
+ end
88
+ ].keys[0]
89
+ else
90
+ 'us-east-1'
91
+ end
92
+ supported_platforms = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:account_attributes].find { |h| h["attributeName"] == "supported-platforms" }["values"]
80
93
  subnets = Fog::Compute::AWS::Mock.data[region][@aws_access_key_id][:subnets].select {|e| subnet_ids.include?(e["subnetId"]) }
81
94
 
82
95
  # http://docs.aws.amazon.com/AmazonVPC/latest/UserGuide/default-vpc.html
@@ -42,11 +42,11 @@ module Fog
42
42
  #
43
43
  def create_role(role_name, assume_role_policy_document, path = '/')
44
44
  request(
45
- 'Action' => 'CreateRole',
46
- 'RoleName' => role_name,
47
- 'AssumeRolePolicyDocument' => assume_role_policy_document,
48
- 'Path' => path,
49
- :parser => Fog::Parsers::AWS::IAM::SingleRole.new
45
+ 'Action' => 'CreateRole',
46
+ 'RoleName' => role_name,
47
+ 'AssumeRolePolicyDocument' => assume_role_policy_document,
48
+ 'Path' => path,
49
+ :parser => Fog::Parsers::AWS::IAM::SingleRole.new
50
50
  )
51
51
  end
52
52
  end
@@ -0,0 +1,62 @@
1
+ module Fog
2
+ module AWS
3
+ class KMS
4
+ class Real
5
+ DEFAULT_KEY_POLICY = <<-JSON
6
+ {
7
+ "Version": "2012-10-17",
8
+ "Id": "key-default-1",
9
+ "Statement": [
10
+ {
11
+ "Sid": "Enable IAM User Permissions",
12
+ "Effect": "Allow",
13
+ "Principal": {
14
+ "AWS": "arn:aws:iam::915445820265:root"
15
+ },
16
+ "Action": "kms:*",
17
+ "Resource": "*"
18
+ }
19
+ ]
20
+ }
21
+ JSON
22
+
23
+ require 'fog/aws/parsers/kms/describe_key'
24
+
25
+ def create_key(policy = nil, description = nil, usage = "ENCRYPT_DECRYPT")
26
+ request(
27
+ 'Action' => 'CreateKey',
28
+ 'Description' => description,
29
+ 'KeyUsage' => usage,
30
+ 'Policy' => policy,
31
+ :parser => Fog::Parsers::AWS::KMS::DescribeKey.new
32
+ )
33
+ end
34
+ end
35
+
36
+ class Mock
37
+ def create_key(policy = nil, description = nil, usage = "ENCRYPT_DECRYPT")
38
+ response = Excon::Response.new
39
+ key_id = UUID.uuid
40
+ key_arn = Fog::AWS::Mock.arn("kms", self.account_id, "key/#{key_id}", @region)
41
+
42
+ key = {
43
+ "KeyUsage" => usage,
44
+ "AWSAccountId" => self.account_id,
45
+ "KeyId" => key_id,
46
+ "Description" => description,
47
+ "CreationDate" => Time.now,
48
+ "Arn" => key_arn,
49
+ "Enabled" => true,
50
+ }
51
+
52
+ # @todo use default policy
53
+
54
+ self.data[:keys][key_id] = key
55
+
56
+ response.body = { "KeyMetadata" => key }
57
+ response
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,27 @@
1
+ module Fog
2
+ module AWS
3
+ class KMS
4
+ class Real
5
+ require 'fog/aws/parsers/kms/describe_key'
6
+
7
+ def describe_key(identifier)
8
+ request(
9
+ 'Action' => 'DescribeKey',
10
+ 'KeyId' => identifier,
11
+ :parser => Fog::Parsers::AWS::KMS::DescribeKey.new
12
+ )
13
+ end
14
+ end
15
+
16
+ class Mock
17
+ def describe_key(identifier)
18
+ response = Excon::Response.new
19
+ key = self.data[:keys][identifier]
20
+
21
+ response.body = { "KeyMetadata" => key }
22
+ response
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ module Fog
2
+ module AWS
3
+ class KMS
4
+ class Real
5
+
6
+ require 'fog/aws/parsers/kms/list_keys'
7
+
8
+ def list_keys(options={})
9
+ params = {}
10
+
11
+ if options[:marker]
12
+ params['Marker'] = options[:marker]
13
+ end
14
+
15
+ if options[:limit]
16
+ params['Limit'] = options[:limit]
17
+ end
18
+
19
+ request({
20
+ 'Action' => 'ListKeys',
21
+ :parser => Fog::Parsers::AWS::KMS::ListKeys.new
22
+ }.merge(params))
23
+ end
24
+ end
25
+
26
+ class Mock
27
+ def list_keys(options={})
28
+ limit = options[:limit]
29
+ marker = options[:marker]
30
+
31
+ if limit
32
+ if limit > 1_000
33
+ raise Fog::AWS::KMS::Error.new(
34
+ "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value less than or equal to 1000"
35
+ )
36
+ elsif limit < 1
37
+ raise Fog::AWS::KMS::Error.new(
38
+ "ValidationError => 1 validation error detected: Value '#{limit}' at 'limit' failed to satisfy constraint: Member must have value greater than or equal to 1"
39
+ )
40
+ end
41
+ end
42
+
43
+ key_set = if marker
44
+ self.data[:markers][marker] || []
45
+ else
46
+ self.data[:keys].inject([]) { |r,(k,v)|
47
+ r << { "KeyId" => k, "KeyArn" => v["Arn"] }
48
+ }
49
+ end
50
+
51
+ keys = if limit
52
+ key_set.slice!(0, limit)
53
+ else
54
+ key_set
55
+ end
56
+
57
+ truncated = keys.size < key_set.size
58
+
59
+ marker = truncated && "metadata/l/#{account_id}/#{UUID.uuid}"
60
+
61
+ response = Excon::Response.new
62
+
63
+ body = {
64
+ 'Keys' => keys,
65
+ 'Truncated' => truncated,
66
+ 'RequestId' => Fog::AWS::Mock.request_id
67
+ }
68
+
69
+ if marker
70
+ self.data[:markers][marker] = key_set
71
+ body.merge!('Marker' => marker)
72
+ end
73
+
74
+ response.body = body
75
+ response.status = 200
76
+
77
+ response
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -25,7 +25,7 @@ module Fog
25
25
  # @param PreferredBackupWindow [String] The daily time range during which automated backups are created if automated backups are enabled
26
26
  # @param PreferredMaintenanceWindow [String] The weekly time range (in UTC) during which system maintenance can occur, which may result in an outage
27
27
  # @param DBSubnetGroupName [String] The name, if any, of the VPC subnet for this RDS instance
28
- # @param PubliclyAcccesible [Boolean] Whether an RDS instance inside of the VPC subnet should have a public-facing endpoint
28
+ # @param PubliclyAccessible [Boolean] Whether an RDS instance inside of the VPC subnet should have a public-facing endpoint
29
29
  # @param VpcSecurityGroups [Array] A list of VPC Security Groups to authorize on this DB instance
30
30
  # @param StorageType [string] Specifies storage type to be associated with the DB Instance. Valid values: standard | gp2 | io1
31
31
  #
@@ -43,9 +43,9 @@ module Fog
43
43
  end
44
44
 
45
45
  request({
46
- 'Action' => 'CreateDBInstance',
46
+ 'Action' => 'CreateDBInstance',
47
47
  'DBInstanceIdentifier' => db_name,
48
- :parser => Fog::Parsers::AWS::RDS::CreateDBInstance.new,
48
+ :parser => Fog::Parsers::AWS::RDS::CreateDBInstance.new,
49
49
  }.merge(options))
50
50
  end
51
51
  end
@@ -78,41 +78,36 @@ module Fog
78
78
  end
79
79
  end
80
80
 
81
- data =
82
- {
83
- "DBInstanceIdentifier"=> db_name,
84
- "DBName" => options["DBName"],
85
- "InstanceCreateTime" => nil,
86
- "AutoMinorVersionUpgrade"=>true,
87
- "Endpoint"=>{},
88
- "ReadReplicaDBInstanceIdentifiers"=>[],
89
- "PreferredMaintenanceWindow"=>"mon:04:30-mon:05:00",
90
- "Engine"=> options["Engine"],
91
- "EngineVersion"=> options["EngineVersion"] || "5.5.12",
92
- "PendingModifiedValues"=>{"MasterUserPassword"=>"****"}, # This clears when is available
93
- "MultiAZ"=> !!options['MultiAZ'],
94
- "MasterUsername"=> options["MasterUsername"],
95
- "DBInstanceClass"=> options["DBInstanceClass"],
96
- "DBInstanceStatus"=>"creating",
97
- "BackupRetentionPeriod"=> options["BackupRetentionPeriod"] || 1,
98
- "AllocatedStorage"=> options["AllocatedStorage"],
99
- "Iops" => options["Iops"],
100
- "DBParameterGroups"=> # I think groups should be in the self.data method
101
- [{"DBParameterGroupName"=>"default.mysql5.5",
102
- "ParameterApplyStatus"=>"in-sync"}],
103
- "DBSecurityGroups"=>
104
- [{"Status"=>"active",
105
- "DBSecurityGroupName"=>"default"}],
106
- "LicenseModel"=>"general-public-license",
107
- "PreferredBackupWindow"=>"08:00-08:30",
108
- # "ReadReplicaSourceDBInstanceIdentifier" => nil,
109
- # "LatestRestorableTime" => nil,
110
- "AvailabilityZone" => options["AvailabilityZone"],
111
- "DBSubnetGroupName" => options["DBSubnetGroupName"],
112
- "PubliclyAccessible" => options["PubliclyAccessible"],
113
- "VpcSecurityGroups" => options["VpcSecurityGroups"],
114
- "StorageType" => options["StorageType"],
115
- }
81
+ data = {
82
+ "AllocatedStorage" => options["AllocatedStorage"],
83
+ "AutoMinorVersionUpgrade" => options["AutoMinorVersionUpgrade"].nil? ? true : options["AutoMinorVersionUpgrade"],
84
+ "AvailabilityZone" => options["AvailabilityZone"],
85
+ "BackupRetentionPeriod" => options["BackupRetentionPeriod"] || 1,
86
+ "CACertificateIdentifier" => "rds-ca-2015",
87
+ "DBInstanceClass" => options["DBInstanceClass"],
88
+ "DBInstanceIdentifier" => db_name,
89
+ "DBInstanceStatus" =>"creating",
90
+ "DBName" => options["DBName"],
91
+ "DBParameterGroups" => [{ "DBParameterGroupName" => "default.mysql5.5", "ParameterApplyStatus" => "in-sync" }],
92
+ "DBSecurityGroups" => [{ "Status" => "active", "DBSecurityGroupName" => "default" }],
93
+ "DBSubnetGroupName" => options["DBSubnetGroupName"],
94
+ "Endpoint" =>{},
95
+ "Engine" => options["Engine"],
96
+ "EngineVersion" => options["EngineVersion"] || "5.5.12",
97
+ "InstanceCreateTime" => nil,
98
+ "Iops" => options["Iops"],
99
+ "LicenseModel" => "general-public-license",
100
+ "MasterUsername" => options["MasterUsername"],
101
+ "MultiAZ" => !!options['MultiAZ'],
102
+ "PendingModifiedValues" => { "MasterUserPassword" => "****" }, # This clears when is available
103
+ "PreferredBackupWindow" => options["PreferredBackupWindow"] || "08:00-08:30",
104
+ "PreferredMaintenanceWindow" => options["PreferredMaintenanceWindow"] || "mon:04:30-mon:05:00",
105
+ "PubliclyAccessible" => !!options["PubliclyAccessible"],
106
+ "ReadReplicaDBInstanceIdentifiers" => [],
107
+ "StorageEncrypted" => false,
108
+ "StorageType" => options["StorageType"] || "standard",
109
+ "VpcSecurityGroups" => options["VpcSecurityGroups"],
110
+ }
116
111
 
117
112
  self.data[:servers][db_name] = data
118
113
  response.body = {
@@ -34,8 +34,10 @@ module Fog
34
34
  source = self.data[:servers][source_identifier]
35
35
  data = {
36
36
  'AllocatedStorage' => source['AllocatedStorage'],
37
- 'AutoMinorVersionUpgrade' => options.key?('AutoMinorVersionUpgrade') ? options['AutoMinorVersionUpgrade'] : true,
37
+ 'AutoMinorVersionUpgrade' => options.key?('AutoMinorVersionUpgrade') ? options['AutoMinorVersionUpgrade'] : source['AutoMinorVersionUpgrade'],
38
38
  'AvailabilityZone' => options['AvailabilityZone'],
39
+ 'BackupRetentionPeriod' => options['BackupRetentionPeriod'] || 0,
40
+ 'CACertificateIdentifier' => "rds-ca-2015",
39
41
  'DBInstanceClass' => options['DBInstanceClass'] || 'db.m1.small',
40
42
  'DBInstanceIdentifier' => instance_identifier,
41
43
  'DBInstanceStatus' => 'creating',
@@ -54,8 +56,11 @@ module Fog
54
56
  'PendingModifiedValues' => {},
55
57
  'PreferredBackupWindow' => '08:00-08:30',
56
58
  'PreferredMaintenanceWindow' => "mon:04:30-mon:05:00",
59
+ 'PubliclyAccessible' => !!options["PubliclyAccessible"],
57
60
  'ReadReplicaDBInstanceIdentifiers' => [],
58
- 'ReadReplicaSourceDBInstanceIdentifier' => source_identifier
61
+ 'ReadReplicaSourceDBInstanceIdentifier' => source_identifier,
62
+ 'StorageType' => options['StorageType'] || 'standard',
63
+ 'StorageEncrypted' => false,
59
64
  }
60
65
  self.data[:servers][instance_identifier] = data
61
66
  self.data[:servers][source_identifier]['ReadReplicaDBInstanceIdentifiers'] << instance_identifier