Class: Fog::AWS::RDS::Mock

Inherits:
Object
  • Object
show all
Defined in:
lib/fog/aws/rds.rb,
lib/fog/aws/requests/rds/describe_events.rb,
lib/fog/aws/requests/rds/copy_db_snapshot.rb,
lib/fog/aws/requests/rds/create_db_cluster.rb,
lib/fog/aws/requests/rds/delete_db_cluster.rb,
lib/fog/aws/requests/rds/create_db_instance.rb,
lib/fog/aws/requests/rds/create_db_snapshot.rb,
lib/fog/aws/requests/rds/delete_db_instance.rb,
lib/fog/aws/requests/rds/delete_db_snapshot.rb,
lib/fog/aws/requests/rds/modify_db_instance.rb,
lib/fog/aws/requests/rds/reboot_db_instance.rb,
lib/fog/aws/requests/rds/add_tags_to_resource.rb,
lib/fog/aws/requests/rds/describe_db_clusters.rb,
lib/fog/aws/requests/rds/promote_read_replica.rb,
lib/fog/aws/requests/rds/describe_db_instances.rb,
lib/fog/aws/requests/rds/describe_db_log_files.rb,
lib/fog/aws/requests/rds/describe_db_snapshots.rb,
lib/fog/aws/requests/rds/create_db_subnet_group.rb,
lib/fog/aws/requests/rds/delete_db_subnet_group.rb,
lib/fog/aws/requests/rds/describe_db_parameters.rb,
lib/fog/aws/requests/rds/list_tags_for_resource.rb,
lib/fog/aws/requests/rds/create_db_security_group.rb,
lib/fog/aws/requests/rds/delete_db_security_group.rb,
lib/fog/aws/requests/rds/create_db_parameter_group.rb,
lib/fog/aws/requests/rds/create_event_subscription.rb,
lib/fog/aws/requests/rds/delete_db_parameter_group.rb,
lib/fog/aws/requests/rds/delete_event_subscription.rb,
lib/fog/aws/requests/rds/describe_db_subnet_groups.rb,
lib/fog/aws/requests/rds/modify_db_parameter_group.rb,
lib/fog/aws/requests/rds/remove_tags_from_resource.rb,
lib/fog/aws/requests/rds/create_db_cluster_snapshot.rb,
lib/fog/aws/requests/rds/delete_db_cluster_snapshot.rb,
lib/fog/aws/requests/rds/describe_db_engine_versions.rb,
lib/fog/aws/requests/rds/describe_db_security_groups.rb,
lib/fog/aws/requests/rds/download_db_logfile_portion.rb,
lib/fog/aws/requests/rds/describe_db_parameter_groups.rb,
lib/fog/aws/requests/rds/describe_event_subscriptions.rb,
lib/fog/aws/requests/rds/modify_db_snapshot_attribute.rb,
lib/fog/aws/requests/rds/describe_db_cluster_snapshots.rb,
lib/fog/aws/requests/rds/describe_db_reserved_instances.rb,
lib/fog/aws/requests/rds/create_db_instance_read_replica.rb,
lib/fog/aws/requests/rds/revoke_db_security_group_ingress.rb,
lib/fog/aws/requests/rds/describe_engine_default_parameters.rb,
lib/fog/aws/requests/rds/authorize_db_security_group_ingress.rb,
lib/fog/aws/requests/rds/restore_db_instance_from_db_snapshot.rb,
lib/fog/aws/requests/rds/restore_db_instance_to_point_in_time.rb,
lib/fog/aws/requests/rds/describe_orderable_db_instance_options.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Mock

Returns a new instance of Mock.



169
170
171
172
173
174
175
176
# File 'lib/fog/aws/rds.rb', line 169

def initialize(options={})
  @use_iam_profile = options[:use_iam_profile]
  @region          = options[:region] || 'us-east-1'

  Fog::AWS.validate_region!(@region)

  setup_credentials(options)
end

Instance Attribute Details

#aws_access_key_idObject

Returns the value of attribute aws_access_key_id.



167
168
169
# File 'lib/fog/aws/rds.rb', line 167

def aws_access_key_id
  @aws_access_key_id
end

#regionObject

Returns the value of attribute region.



167
168
169
# File 'lib/fog/aws/rds.rb', line 167

def region
  @region
end

Class Method Details

.dataObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/fog/aws/rds.rb', line 109

def self.data
  @data ||= Hash.new do |hash, region|
    hash[region] = Hash.new do |region_hash, key|
      region_hash[key] = {
        :clusters            => {},
        :cluster_snapshots   => {},
        :servers             => {},
        :security_groups     => {},
        :subnet_groups       => {},
        :snapshots           => {},
        :event_subscriptions => {},
        :default_parameters  => [
          {
            "DataType"      => "integer",
            "Source"        => "engine-default",
            "Description"   => "Intended for use with master-to-master replication, and can be used to control the operation of AUTO_INCREMENT columns",
            "ApplyType"     => "dynamic",
            "AllowedValues" => "1-65535",
            "ParameterName" => "auto_increment_increment"
          }
        ],
        :db_engine_versions  => [
          {
            'Engine'                     => "mysql",
            'DBParameterGroupFamily'     => "mysql5.1",
            'DBEngineDescription'        => "MySQL Community Edition",
            'EngineVersion'              => "5.1.57",
            'DBEngineVersionDescription' => "MySQL 5.1.57"
          },
          {
            'Engine'                     => "postgres",
            'DBParameterGroupFamily'     => "postgres9.3",
            'DBEngineDescription'        => "PostgreSQL",
            'EngineVersion'              => "9.3.5",
            'DBEngineVersionDescription' => "PostgreSQL 9.3.5"
          },
        ],
        :parameter_groups    => {
          "default.mysql5.1" => {
            "DBParameterGroupFamily" => "mysql5.1",
            "Description"            => "Default parameter group for mysql5.1",
            "DBParameterGroupName"   => "default.mysql5.1"
          },
          "default.mysql5.5" => {
            "DBParameterGroupFamily" => "mysql5.5",
            "Description"            => "Default parameter group for mysql5.5",
            "DBParameterGroupName"   => "default.mysql5.5"
          }
        }
      }
    end
  end
end

.resetObject



163
164
165
# File 'lib/fog/aws/rds.rb', line 163

def self.reset
  @data = nil
end

Instance Method Details

#add_tags_to_resource(rds_id, tags) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/fog/aws/requests/rds/add_tags_to_resource.rb', line 28

def add_tags_to_resource(rds_id, tags)
  response = Excon::Response.new
  if server = data[:servers][rds_id]
    data[:tags][rds_id].merge! tags
    response.status = 200
    response.body = {
      'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id }
    }
    response
  else
    raise Fog::AWS::RDS::NotFound, "DBInstance #{rds_id} not found"
  end
end

#authorize_db_security_group_ingress(name, opts = {}) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/fog/aws/requests/rds/authorize_db_security_group_ingress.rb', line 31

def authorize_db_security_group_ingress(name, opts = {})
  unless opts.key?('CIDRIP') || ((opts.key?('EC2SecurityGroupName') || opts.key?('EC2SecurityGroupId')) && opts.key?('EC2SecurityGroupOwnerId'))
    raise ArgumentError, 'Must specify CIDRIP, or one of EC2SecurityGroupName or EC2SecurityGroupId, and EC2SecurityGroupOwnerId'
  end

  if ec2_security_group_id = opts.delete("EC2SecurityGroupId")
    ec2_security_group = (Fog::AWS::Compute::Mock.data[self.region][self.aws_access_key_id][:security_groups] || {}).values.detect { |sg| sg['groupId'] == ec2_security_group_id }
    opts['EC2SecurityGroupName'] = ec2_security_group['groupName']
  end

  response = Excon::Response.new

  if sec_group = self.data[:security_groups][name]
    if opts.key?('CIDRIP')
      if sec_group['IPRanges'].find{|h| h['CIDRIP'] == opts['CIDRIP']}
        raise Fog::AWS::RDS::AuthorizationAlreadyExists.new("AuthorizationAlreadyExists => #{opts['CIDRIP']} is alreay defined")
      end
      sec_group['IPRanges'] << opts.merge({"Status" => 'authorizing'})
    else
      if sec_group['EC2SecurityGroups'].find{|h| h['EC2SecurityGroupName'] == opts['EC2SecurityGroupName'] || h['EC2SecurityGroupId'] == opts['EC2SecurityGroupId']}
        raise Fog::AWS::RDS::AuthorizationAlreadyExists.new("AuthorizationAlreadyExists => #{opts['EC2SecurityGroupName']} is alreay defined")
      end
      sec_group['EC2SecurityGroups'] << opts.merge({"Status" => 'authorizing'})
    end
    response.status = 200
    response.body = {
      "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
      'AuthorizeDBSecurityGroupIngressResult' => {
        'DBSecurityGroup' => sec_group
      }
    }
    response
  else
    raise Fog::AWS::RDS::NotFound.new("DBSecurityGroupNotFound => #{name} not found")
  end
end

#copy_db_snapshot(source_db_snapshot_identifier, target_db_snapshot_identifier, copy_tags = false) ⇒ Object

Usage

Fog::AWS.copy_db_snapshot(“snap-original-id”, “snap-backup-id”, true)



37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/fog/aws/requests/rds/copy_db_snapshot.rb', line 37

def copy_db_snapshot(source_db_snapshot_identifier, target_db_snapshot_identifier, copy_tags = false)
  response = Excon::Response.new
  response.status = 200
  snapshot_id =  Fog::AWS::Mock.snapshot_id
  data = self.data[:snapshots]["#{source_db_snapshot_identifier}"]
  data['DBSnapshotIdentifier'] = snapshot_id
  self.data[:snapshots][snapshot_id] = data
  response.body = {
    'requestId' => Fog::AWS::Mock.request_id,
    'CopyDBSnapshotResult' => {'DBSnapshot' => data.dup}
  }
  response
end

#create_db_cluster(cluster_name, options = {}) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/fog/aws/requests/rds/create_db_cluster.rb', line 50

def create_db_cluster(cluster_name, options={})
  response = Excon::Response.new
  if self.data[:clusters][cluster_name]
    raise Fog::AWS::RDS::IdentifierTaken.new("DBClusterAlreadyExists")
  end

  required_params = %w(Engine MasterUsername MasterUserPassword)
  required_params.each do |key|
    unless options.key?(key) && options[key] && !options[key].to_s.empty?
      raise Fog::AWS::RDS::NotFound.new("The request must contain the parameter #{key}")
    end
  end

  vpc_security_groups = Array(options.delete("VpcSecurityGroups")).map do |group_id|
    {"VpcSecurityGroupId" => group_id }
  end

  data = {
    'AllocatedStorage'           => "1",
    'BackupRetentionPeriod'      => (options["BackupRetentionPeriod"] || 35).to_s,
    'ClusterCreateTime'          => Time.now,
    'DBClusterIdentifier'        => cluster_name,
    'DBClusterMembers'           => [],
    'DBClusterParameterGroup'    => options['DBClusterParameterGroup'] || "default.aurora5.6",
    'DBSubnetGroup'              => options["DBSubnetGroup"] || "default",
    'Endpoint'                   => "#{cluster_name}.cluster-#{Fog::Mock.random_hex(8)}.#{@region}.rds.amazonaws.com",
    'Engine'                     => options["Engine"] || "aurora5.6",
    'EngineVersion'              => options["EngineVersion"] || "5.6.10a",
    'MasterUsername'             => options["MasterUsername"],
    'Port'                       => options["Port"] || "3306",
    'PreferredBackupWindow'      => options["PreferredBackupWindow"] || "04:45-05:15",
    'PreferredMaintenanceWindow' => options["PreferredMaintenanceWindow"] || "sat:05:56-sat:06:26",
    'Status'                     => "available",
    'StorageEncrypted'           => options["StorageEncrypted"] || false,
    'VpcSecurityGroups'          => vpc_security_groups,
  }

  self.data[:clusters][cluster_name] = data
  response.body = {
    "ResponseMetadata" =>      { "RequestId" => Fog::AWS::Mock.request_id },
    "CreateDBClusterResult" => { "DBCluster" => data.dup.reject { |k,v| k == 'ClusterCreateTime' } }
  }
  response.status = 200
  response
end

#create_db_cluster_snapshot(identifier, name) ⇒ Object

Raises:

  • (Fog::AWS::RDS::NotFound)


30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fog/aws/requests/rds/create_db_cluster_snapshot.rb', line 30

def create_db_cluster_snapshot(identifier, name)
  response = Excon::Response.new

  if data[:cluster_snapshots][name]
    raise Fog::AWS::RDS::IdentifierTaken.new
  end

  cluster = self.data[:clusters][identifier]

  raise Fog::AWS::RDS::NotFound.new("DBCluster #{identifier} not found") unless cluster

  data = {
    'AllocatedStorage'            => cluster['AllocatedStorage'].to_i,
    'ClusterCreateTime'           => cluster['ClusterCreateTime'],
    'DBClusterIdentifier'         => identifier,
    'DBClusterSnapshotIdentifier' => name,
    'Engine'                      => cluster['Engine'],
    'EngineVersion'               => cluster['EngineVersion'],
    'LicenseModel'                => cluster['Engine'],
    'MasterUsername'              => cluster['MasterUsername'],
    'SnapshotCreateTime'          => Time.now,
    'SnapshotType'                => 'manual',
    'StorageEncrypted'            => cluster["StorageEncrypted"],
    'Status'                      => 'creating',
  }

  self.data[:cluster_snapshots][name] = data

  response.body = {
    "ResponseMetadata"              => { "RequestId" => Fog::AWS::Mock.request_id },
    "CreateDBClusterSnapshotResult" => { "DBClusterSnapshot" => data.dup },
  }
  self.data[:cluster_snapshots][name]['SnapshotCreateTime'] = Time.now
  response
end

#create_db_instance(db_name, options = {}) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/fog/aws/requests/rds/create_db_instance.rb', line 54

def create_db_instance(db_name, options={})
  response = Excon::Response.new
  if self.data[:servers] and self.data[:servers][db_name]
    # I don't know how to raise an exception that contains the excon data
    #response.status = 400
    #response.body = {
    #  'Code' => 'DBInstanceAlreadyExists',
    #  'Message' => "DB Instance already exists"
    #}
    #return response
    raise Fog::AWS::RDS::IdentifierTaken.new("DBInstanceAlreadyExists #{response.body.to_s}")
  end

  # These are the required parameters according to the API
  required_params = %w(DBInstanceClass Engine)
  required_params += %w{AllocatedStorage DBInstanceClass Engine MasterUserPassword MasterUsername } unless options["DBClusterIdentifier"]
  required_params.each do |key|
    unless options.key?(key) and options[key] and !options[key].to_s.empty?
      #response.status = 400
      #response.body = {
      #  'Code' => 'MissingParameter',
      #  'Message' => "The request must contain the parameter #{key}"
      #}
      #return response
      raise Fog::AWS::RDS::NotFound.new("The request must contain the parameter #{key}")
    end
  end

  if !!options["MultiAZ"] && !!options["AvailabilityZone"]
    raise Fog::AWS::RDS::InvalidParameterCombination.new('Requesting a specific availability zone is not valid for Multi-AZ instances.')
  end

  ec2 = Fog::AWS::Compute::Mock.data[@region][@aws_access_key_id]

  db_parameter_groups     = if pg_name = options.delete("DBParameterGroupName")
                              group = self.data[:parameter_groups][pg_name]
                              if group
                                [{"DBParameterGroupName" => pg_name, "ParameterApplyStatus" => "in-sync" }]
                              else
                                raise Fog::AWS::RDS::NotFound.new("Parameter group does not exist")
                              end
                            else
                              [{ "DBParameterGroupName" => "default.mysql5.5", "ParameterApplyStatus" => "in-sync" }]
                            end
  db_security_group_names = Array(options.delete("DBSecurityGroups"))
  rds_security_groups     = self.data[:security_groups].values
  ec2_security_groups     = ec2[:security_groups].values
  vpc                     = !ec2[:account_attributes].find { |h| "supported-platforms" == h["attributeName"] }["values"].include?("EC2")

  db_security_groups = db_security_group_names.map do |group_name|
    unless rds_security_groups.find { |sg| sg["DBSecurityGroupName"] == group_name }
      raise Fog::AWS::RDS::Error.new("InvalidParameterValue => Invalid security group , groupId= , groupName=#{group_name}")
    end

    {"Status" => "active", "DBSecurityGroupName" => group_name }
  end

  if !vpc && db_security_groups.empty?
    db_security_groups << { "Status" => "active", "DBSecurityGroupName" => "default" }
  end

  vpc_security_groups = Array(options.delete("VpcSecurityGroups")).map do |group_id|
    unless ec2_security_groups.find { |sg| sg["groupId"] == group_id }
      raise Fog::AWS::RDS::Error.new("InvalidParameterValue => Invalid security group , groupId=#{group_id} , groupName=")
    end

    {"Status" => "active", "VpcSecurityGroupId" => group_id }
  end

  if options["Engine"] == "aurora" && ! options["DBClusterIdentifier"]
    raise Fog::AWS::RDS::Error.new("InvalidParameterStateValue => Standalone instances for this engine are not supported")
  end

  if cluster_id = options["DBClusterIdentifier"]
    if vpc_security_groups.any?
      raise Fog::AWS::RDS::Error.new("InvalidParameterCombination => The requested DB Instance will be a member of a DB Cluster and its vpc security group should not be set directly.")
    end

    if options["MultiAZ"]
      raise Fog::AWS::RDS::Error.new("InvalidParameterCombination => VPC Multi-AZ DB Instances are not available for engine: aurora")
    end

    %w(AllocatedStorage BackupRetentionPeriod MasterUsername MasterUserPassword).each do |forbidden|
      raise Fog::AWS::RDS::Error.new("InvalidParameterCombination => The requested DB Instance will be a member of a DB Cluster and its #{forbidden} should not be set directly.") if options[forbidden]
    end

    options["StorageType"] = "aurora"

    cluster = self.data[:clusters][cluster_id]

    member = {"DBInstanceIdentifier" => db_name, "master" => cluster['DBClusterMembers'].empty?}
    cluster['DBClusterMembers'] << member
    self.data[:clusters][cluster_id] = cluster
  end

  data = {
    "AllocatedStorage"                 => options["AllocatedStorage"],
    "AutoMinorVersionUpgrade"          => options["AutoMinorVersionUpgrade"].nil? ? true : options["AutoMinorVersionUpgrade"],
    "AvailabilityZone"                 => options["AvailabilityZone"],
    "BackupRetentionPeriod"            => options["BackupRetentionPeriod"] || 1,
    "CACertificateIdentifier"          => "rds-ca-2015",
    "DBClusterIdentifier"              => options["DBClusterIdentifier"],
    "DBInstanceClass"                  => options["DBInstanceClass"],
    "DBInstanceIdentifier"             => db_name,
    "DBInstanceStatus"                 =>"creating",
    "DBName"                           => options["DBName"],
    "DBParameterGroups"                => db_parameter_groups,
    "DBSecurityGroups"                 => db_security_groups,
    "DBSubnetGroupName"                => options["DBSubnetGroupName"],
    "Endpoint"                         =>{},
    "Engine"                           => options["Engine"],
    "EngineVersion"                    => options["EngineVersion"] || "5.5.12",
    "InstanceCreateTime"               => nil,
    "Iops"                             => options["Iops"],
    "LicenseModel"                     => "general-public-license",
    "MasterUsername"                   => cluster_id ? cluster["MasterUsername"] : options["MasterUsername"],
    "MultiAZ"                          => !!options["MultiAZ"],
    "PendingModifiedValues"            => { "MasterUserPassword" => "****" }, # This clears when is available
    "PreferredBackupWindow"            => options["PreferredBackupWindow"] || "08:00-08:30",
    "PreferredMaintenanceWindow"       => options["PreferredMaintenanceWindow"] || "mon:04:30-mon:05:00",
    "PubliclyAccessible"               => !!options["PubliclyAccessible"],
    "ReadReplicaDBInstanceIdentifiers" => [],
    "StorageEncrypted"                 => cluster_id ? cluster["StorageEncrypted"] : (options["StorageEncrypted"] || false),
    "StorageType"                      => options["StorageType"] || "standard",
    "VpcSecurityGroups"                => vpc_security_groups,
  }

  self.data[:servers][db_name] = data
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "CreateDBInstanceResult"=> {"DBInstance"=> data}
  }
  response.status = 200
  # This values aren't showed at creating time but at available time
  self.data[:servers][db_name]["InstanceCreateTime"] = Time.now
  self.data[:tags] ||= {}
  self.data[:tags][db_name] = {}
  response
end

#create_db_instance_read_replica(instance_identifier, source_identifier, options = {}) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/fog/aws/requests/rds/create_db_instance_read_replica.rb', line 30

def create_db_instance_read_replica(instance_identifier, source_identifier, options={})
  # TODO: throw error when instance_identifier already exists,
  # or source_identifier doesn't exist

  source = self.data[:servers][source_identifier]
  data = {
    'AllocatedStorage'                      => source['AllocatedStorage'],
    'AutoMinorVersionUpgrade'               => options.key?('AutoMinorVersionUpgrade') ? options['AutoMinorVersionUpgrade'] : source['AutoMinorVersionUpgrade'],
    'AvailabilityZone'                      => options['AvailabilityZone'],
    'BackupRetentionPeriod'                 => options['BackupRetentionPeriod'] || 0,
    'CACertificateIdentifier'               => "rds-ca-2015",
    'DBInstanceClass'                       => options['DBInstanceClass'] || 'db.m1.small',
    'DBInstanceIdentifier'                  => instance_identifier,
    'DBInstanceStatus'                      => 'creating',
    'DBName'                                => source['DBName'],
    'DBParameterGroups'                     => source['DBParameterGroups'],
    'DBSecurityGroups'                      => source['DBSecurityGroups'],
    'Endpoint'                              => {},
    'Engine'                                => source['Engine'],
    'EngineVersion'                         => source['EngineVersion'],
    'InstanceCreateTime'                    => nil,
    'Iops'                                  => source['Iops'],
    'LatestRestorableTime'                  => nil,
    'LicenseModel'                          => 'general-public-license',
    'MasterUsername'                        => source['MasterUsername'],
    'MultiAZ'                               => false,
    'PendingModifiedValues'                 => {},
    'PreferredBackupWindow'                 => '08:00-08:30',
    'PreferredMaintenanceWindow'            => "mon:04:30-mon:05:00",
    'PubliclyAccessible'                    => !!options["PubliclyAccessible"],
    'ReadReplicaDBInstanceIdentifiers'      => [],
    'ReadReplicaSourceDBInstanceIdentifier' => source_identifier,
    'StorageType'                           => options['StorageType'] || 'standard',
    'StorageEncrypted'                      => false,
    'VpcSecurityGroups'                     => source['VpcSecurityGroups'],
  }
  self.data[:servers][instance_identifier] = data
  self.data[:servers][source_identifier]['ReadReplicaDBInstanceIdentifiers'] << instance_identifier

  response = Excon::Response.new
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "CreateDBInstanceReadReplicaResult"=> {"DBInstance"=> data}
  }
  response.status = 200
  # This values aren't showed at creating time but at available time
  self.data[:servers][instance_identifier]["InstanceCreateTime"] = Time.now

  response
end

#create_db_parameter_group(group_name, group_family, description) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/fog/aws/requests/rds/create_db_parameter_group.rb', line 30

def create_db_parameter_group(group_name, group_family, description)
  response = Excon::Response.new
  if self.data[:parameter_groups] and self.data[:parameter_groups][group_name]
    raise Fog::AWS::RDS::IdentifierTaken.new("Parameter group #{group_name} already exists")
  end

  data = {
    'DBParameterGroupName' => group_name,
    'DBParameterGroupFamily' => group_family.downcase,
    'Description' => description
  }
  self.data[:parameter_groups][group_name] = data

  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "CreateDBParameterGroupResult"=> {"DBParameterGroup"=> data}
  }
  response.status = 200
  response
end

#create_db_security_group(name, description = name) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/fog/aws/requests/rds/create_db_security_group.rb', line 26

def create_db_security_group(name, description = name)
  response = Excon::Response.new
  if self.data[:security_groups] and self.data[:security_groups][name]
    raise Fog::AWS::RDS::IdentifierTaken.new("DBInstanceAlreadyExists => The security group '#{name}' already exists")
  end

  data = {
    'DBSecurityGroupName' => name,
    'DBSecurityGroupDescription' => description,
    'EC2SecurityGroups' => [],
    'IPRanges' => [],
    'OwnerId' => '0123456789'
  }
  self.data[:security_groups][name] = data
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    'CreateDBSecurityGroupResult' => { 'DBSecurityGroup' => data }
  }
  response
end

#create_db_snapshot(identifier, name) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fog/aws/requests/rds/create_db_snapshot.rb', line 26

def create_db_snapshot(identifier, name)
  response = Excon::Response.new
  if data[:snapshots][name]
    raise Fog::AWS::RDS::IdentifierTaken.new
  end

  server_data = data[:servers][identifier]

  unless server_data
    raise Fog::AWS::RDS::NotFound.new("DBInstance #{identifier} not found")
  end

  # TODO: raise an error if the server isn't in 'available' state

  snapshot_data = {
    'Status'               => 'creating',
    'SnapshotType'         => 'manual',
    'DBInstanceIdentifier' => identifier,
    'DBSnapshotIdentifier' => name,
    'InstanceCreateTime'   => Time.now
  }
  # Copy attributes from server
  %w(Engine EngineVersion AvailabilityZone AllocatedStorage Iops MasterUsername InstanceCreateTime StorageType).each do |key|
    snapshot_data[key] = server_data[key]
  end
  snapshot_data['Port'] = server_data['Endpoint']['Port']

  self.data[:snapshots][name] = snapshot_data

  # TODO: put the server in 'modifying' state

  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "CreateDBSnapshotResult"=> {"DBSnapshot"=> snapshot_data.dup}
  }
  response.status = 200
  # SnapshotCreateTime is not part of the response.
  self.data[:snapshots][name]['SnapshotCreateTime'] = Time.now
  response
end

#create_db_subnet_group(name, subnet_ids, description = name) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/fog/aws/requests/rds/create_db_subnet_group.rb', line 27

def create_db_subnet_group(name, subnet_ids, description = name)
  response = Excon::Response.new
  if self.data[:subnet_groups] && self.data[:subnet_groups][name]
    raise Fog::AWS::RDS::IdentifierTaken.new("DBSubnetGroupAlreadyExists => The subnet group '#{name}' already exists")
  end

  # collection = Fog::AWS::Compute.new(:aws_access_key_id => 'mock key', :aws_secret_access_key => 'mock secret')
  compute_data = Fog::AWS::Compute::Mock.data[self.region][self.aws_access_key_id]

  subnets = subnet_ids.map do |snid|
    subnet = compute_data[:subnets].detect { |s| s['subnetId'] == snid }
    raise Fog::AWS::RDS::NotFound.new("InvalidSubnet => The subnet '#{snid}' was not found") if subnet.nil?
    subnet
  end
  vpc_id = subnets.first['vpcId']

  data = {
    'DBSubnetGroupName' => name,
    'DBSubnetGroupDescription' => description,
    'SubnetGroupStatus' => 'Complete',
    'Subnets' => subnet_ids,
    'VpcId' => vpc_id
  }
  self.data[:subnet_groups][name] = data
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    'CreateDBSubnetGroupResult' => { 'DBSubnetGroup' => data }
  }
  response
end

#create_event_subscription(options = {}) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/fog/aws/requests/rds/create_event_subscription.rb', line 37

def create_event_subscription(options={})
  response = Excon::Response.new
  name     = options.delete('SubscriptionName')
  arn      = options.delete('SnsTopicArn')

  if self.data[:event_subscriptions][name]
    raise Fog::AWS::RDS::IdentifierTaken.new("SubscriptionAlreadyExist => Subscription already exists")
  end

  subscription = {
    'CustSubscriptionId' => name,
    'EventCategories'    => options['EventCategories'] || [],
    'SourceType'         => options['SourceType'],
    'Enabled'            => options.fetch(:enabled, "true"),
    'Status'             => 'creating',
    'CreationTime'       => Time.now,
    'SnsTopicArn'        => arn,
  }

  self.data[:event_subscriptions][name] = subscription

  response.body = {
    "ResponseMetaData" => {"RequestId" => Fog::AWS::Mock.request_id},
    "CreateEventSubscriptionResult" => { "EventSubscription" => subscription }
  }
  response
end

#dataObject



178
179
180
# File 'lib/fog/aws/rds.rb', line 178

def data
  self.class.data[@region][@aws_access_key_id]
end

#delete_db_cluster(identifier, snapshot_identifier, skip_snapshot = false) ⇒ Object

Raises:

  • (Fog::AWS::RDS::Error)


32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/fog/aws/requests/rds/delete_db_cluster.rb', line 32

def delete_db_cluster(identifier, snapshot_identifier, skip_snapshot = false)
  response = Excon::Response.new

  cluster = self.data[:clusters][identifier] || raise(Fog::AWS::RDS::NotFound.new("DBCluster #{identifier} not found"))

  raise Fog::AWS::RDS::Error.new("InvalidDBClusterStateFault => Cluster cannot be deleted, it still contains DB instances in non-deleting state.") if cluster["DBClusterMembers"].any?

  unless skip_snapshot
    create_db_cluster_snapshot(identifier, snapshot_identifier)
  end

  self.data[:clusters].delete(identifier)

  response.status = 200
  response.body   = {
    "ResponseMetadata"      => { "RequestId" => Fog::AWS::Mock.request_id },
    "DeleteDBClusterResult" => { "DBCluster" => cluster}
  }
  response
end

#delete_db_cluster_snapshot(name) ⇒ Object

Raises:

  • (Fog::AWS::RDS::NotFound)


27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fog/aws/requests/rds/delete_db_cluster_snapshot.rb', line 27

def delete_db_cluster_snapshot(name)
  response = Excon::Response.new
  snapshot = self.data[:cluster_snapshots].delete(name)

  raise Fog::AWS::RDS::NotFound.new("DBClusterSnapshotNotFound => #{name} not found") unless snapshot

  response.status = 200
  response.body = {
    "ResponseMetadata"              => {"RequestId"         => Fog::AWS::Mock.request_id},
    "DeleteDBClusterSnapshotResult" => {"DBClusterSnapshot" => snapshot}
  }
  response
end

#delete_db_instance(identifier, snapshot_identifier, skip_snapshot = false) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fog/aws/requests/rds/delete_db_instance.rb', line 30

def delete_db_instance(identifier, snapshot_identifier, skip_snapshot = false)
  response = Excon::Response.new


  server_set = self.data[:servers][identifier] ||
    raise(Fog::AWS::RDS::NotFound.new("DBInstance #{identifier} not found"))

  unless skip_snapshot
    if server_set["ReadReplicaSourceDBInstanceIdentifier"]
      raise Fog::AWS::RDS::Error.new("InvalidParameterCombination => FinalDBSnapshotIdentifier can not be specified when deleting a replica instance")
    elsif server_set["DBClusterIdentifier"] && snapshot_identifier # for cluster instances, you must pass in skip_snapshot = false, but not specify a snapshot identifier
      raise Fog::AWS::RDS::Error.new("InvalidParameterCombination => FinalDBSnapshotIdentifier can not be specified when deleting a cluster instance")
    elsif server_set["DBClusterIdentifier"] && !snapshot_identifier && !skip_snapshot
      #no-op
    else
      create_db_snapshot(identifier, snapshot_identifier)
    end
  end

  cluster = self.data[:clusters].values.detect { |c| c["DBClusterMembers"].any? { |m| m["DBInstanceIdentifier"] == identifier } }

  if cluster
    cluster["DBClusterMembers"].delete_if { |v| v["DBInstanceIdentifier"] == identifier }
    self.data[:clusters][cluster["DBClusterIdentifier"]] = cluster
  end

  self.data[:servers].delete(identifier)

  response.status = 200
  response.body = {
    "ResponseMetadata"       => { "RequestId"  => Fog::AWS::Mock.request_id },
    "DeleteDBInstanceResult" => { "DBInstance" => server_set }
  }
  response
end

#delete_db_parameter_group(group_name) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fog/aws/requests/rds/delete_db_parameter_group.rb', line 25

def delete_db_parameter_group(group_name)
  response = Excon::Response.new

  if self.data[:parameter_groups].delete(group_name)
    response.status = 200
    response.body = {
      "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    }
    response
  else
    raise Fog::AWS::RDS::NotFound.new("DBParameterGroup not found: #{group_name}")
  end
end

#delete_db_security_group(name, description = name) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/fog/aws/requests/rds/delete_db_security_group.rb', line 24

def delete_db_security_group(name, description = name)
  response = Excon::Response.new

  if self.data[:security_groups].delete(name)
    response.status = 200
    response.body = {
      "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    }
    response
  else
    raise Fog::AWS::RDS::NotFound.new("DBSecurityGroupNotFound => #{name} not found")
  end
end

#delete_db_snapshot(name) ⇒ Object

Raises:

  • (Fog::AWS::RDS::NotFound)


25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fog/aws/requests/rds/delete_db_snapshot.rb', line 25

def delete_db_snapshot(name)
  # TODO: raise error if snapshot isn't 'available'
  response = Excon::Response.new
  snapshot_data = self.data[:snapshots].delete(name)
  snapshot_data = self.data[:cluster_snapshots].delete(name) unless snapshot_data

  raise Fog::AWS::RDS::NotFound.new("DBSnapshotNotFound => #{name} not found") unless snapshot_data

  response.status = 200
  response.body = {
    "ResponseMetadata"=> { "RequestId"=> Fog::AWS::Mock.request_id },
    "DeleteDBSnapshotResult"=> {"DBSnapshot"=> snapshot_data}
  }
  response
end

#delete_db_subnet_group(name) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/fog/aws/requests/rds/delete_db_subnet_group.rb', line 23

def delete_db_subnet_group(name)
  response = Excon::Response.new
  unless self.data[:subnet_groups] && self.data[:subnet_groups][name]
    raise Fog::AWS::RDS::NotFound.new("DBSubnetGroupNotFound => The subnet group '#{name}' doesn't exists")
  end

  self.data[:subnet_groups].delete(name)

  response.body = {
    'ResponseMetadata'=>{ 'RequestId'=> Fog::AWS::Mock.request_id },
    'return' => true,
  }
  response
end

#delete_event_subscription(name) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/fog/aws/requests/rds/delete_event_subscription.rb', line 25

def delete_event_subscription(name)
  response = Excon::Response.new

  if data = self.data[:event_subscriptions][name]
    data['Status'] = 'deleting'
    self.data[:event_subscriptions][name] = data

    response.status = 200
    response.body = {
      "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    }
    response
  else
    raise Fog::AWS::RDS::NotFound.new("EventSubscriptionNotFound => #{name} not found")
  end
end

#describe_db_cluster_snapshots(opts = {}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/fog/aws/requests/rds/describe_db_cluster_snapshots.rb', line 34

def describe_db_cluster_snapshots(opts={})
  response = Excon::Response.new
  snapshots = self.data[:cluster_snapshots].values

  if opts[:identifier]
    snapshots = snapshots.select { |snapshot| snapshot['DBClusterIdentifier'] == opts[:identifier] }
  end

  if opts[:snapshot_id]
    snapshots = snapshots.select { |snapshot| snapshot['DBClusterSnapshotIdentifier'] == opts[:snapshot_id] }
    raise Fog::AWS::RDS::NotFound.new("DBClusterSnapshot #{opts[:snapshot_id]} not found") if snapshots.empty?
  end

  snapshots.each do |snapshot|
    case snapshot['Status']
    when 'creating'
      if Time.now - snapshot['SnapshotCreateTime'] > Fog::Mock.delay
        snapshot['Status'] = 'available'
      end
    end
  end

  response.status = 200
  response.body = {
    'ResponseMetadata'                 => { "RequestId"          => Fog::AWS::Mock.request_id },
    'DescribeDBClusterSnapshotsResult' => { 'DBClusterSnapshots' => snapshots }
  }
  response
end

#describe_db_clusters(identifier = nil, opts = {}) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/fog/aws/requests/rds/describe_db_clusters.rb', line 30

def describe_db_clusters(identifier=nil, opts={})
  response    = Excon::Response.new
  cluster_set = []

  if identifier
    if cluster = self.data[:clusters][identifier]
      cluster_set << cluster
    else
      raise Fog::AWS::RDS::NotFound.new("DBCluster #{identifier} not found")
    end
  else
    cluster_set = self.data[:clusters].values
  end

  response.status = 200
  response.body = {
    "ResponseMetadata"         => { "RequestId"  => Fog::AWS::Mock.request_id },
    "DescribeDBClustersResult" => { "DBClusters" => cluster_set }
  }
  response
end

#describe_db_engine_versions(opts = {}) ⇒ Object



24
25
26
27
28
29
30
31
32
33
# File 'lib/fog/aws/requests/rds/describe_db_engine_versions.rb', line 24

def describe_db_engine_versions(opts={})
  response = Excon::Response.new

  response.status = 200
  response.body = {
    "ResponseMetadata"               => { "RequestId"        => Fog::AWS::Mock.request_id },
    "DescribeDBEngineVersionsResult" => { "DBEngineVersions" => self.data[:db_engine_versions] }
  }
  response
end

#describe_db_instances(identifier = nil, opts = {}) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fog/aws/requests/rds/describe_db_instances.rb', line 32

def describe_db_instances(identifier=nil, opts={})
  response = Excon::Response.new
  server_set = []
  if identifier
    if specified_server = self.data[:servers][identifier]
      server_set << specified_server
    else
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{identifier} not found")
    end
  else
    server_set = self.data[:servers].values
  end

  server_set.each do |server|
     case server["DBInstanceStatus"]
     when "creating"
       if Time.now - server['InstanceCreateTime'] >= Fog::Mock.delay * 2
         server["DBInstanceStatus"] = "available"
         server["AvailabilityZone"] ||= region + 'a'
         server["Endpoint"] = {"Port"=>3306,
                               "Address"=> Fog::AWS::Mock.rds_address(server["DBInstanceIdentifier"],region) }
         server["PendingModifiedValues"] = {}
       end
      when "rebooting"
        if Time.now - self.data[:reboot_time] >= Fog::Mock.delay
          # apply pending modified values
          server.merge!(server["PendingModifiedValues"])
          server["PendingModifiedValues"] = {}

          server["DBInstanceStatus"] = 'available'
          self.data.delete(:reboot_time)
        end
      when "modifying"
        # TODO there are some fields that only applied after rebooting
        if Time.now - self.data[:modify_time] >= Fog::Mock.delay
          if new_id = server["PendingModifiedValues"] && server["PendingModifiedValues"]["DBInstanceIdentifier"]
            self.data[:servers][new_id] = self.data[:servers].delete(server["DBInstanceIdentifier"])
          end

          server.merge!(server["PendingModifiedValues"])
          server["PendingModifiedValues"] = {}
          server["DBInstanceStatus"] = 'available'
        end
      when "available" # I'm not sure if amazon does this
        unless server["PendingModifiedValues"].empty?
          server["DBInstanceStatus"] = 'modifying'
        end
     end
  end

  response.status = 200
  response.body = {
    "ResponseMetadata"          => { "RequestId"   => Fog::AWS::Mock.request_id },
    "DescribeDBInstancesResult" => { "DBInstances" => server_set }
  }
  response
end

#describe_db_log_files(rds_id = nil, opts = {}) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/fog/aws/requests/rds/describe_db_log_files.rb', line 37

def describe_db_log_files(rds_id=nil, opts={})
  response = Excon::Response.new
  log_file_set = []

  if rds_id
    if server = self.data[:servers][rds_id]
      log_file_set << {"LastWritten" => Time.parse('2013-07-05 17:00:00 -0700'), "LogFileName" => "error/mysql-error.log", "Size" => 0}
      log_file_set << {"LastWritten" => Time.parse('2013-07-05 17:10:00 -0700'), "LogFileName" => "error/mysql-error-running.log", "Size" => 0}
      log_file_set << {"LastWritten" => Time.parse('2013-07-05 17:20:00 -0700'), "LogFileName" => "error/mysql-error-running.log.0", "Size" => 8220}
      log_file_set << {"LastWritten" => Time.parse('2013-07-05 17:30:00 -0700'), "LogFileName" => "error/mysql-error-running.log.1", "Size" => 0}
    else
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{rds_id} not found")
    end
  else
    raise Fog::AWS::RDS::NotFound.new('An identifier for an RDS instance must be provided')
  end

  response.status = 200
  response.body = {
      "ResponseMetadata" => { "RequestId" => Fog::AWS::Mock.request_id },
      "DescribeDBLogFilesResult" => { "DBLogFiles" => log_file_set }
  }
  response
end

#describe_db_parameter_groups(name = nil, opts = {}) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/fog/aws/requests/rds/describe_db_parameter_groups.rb', line 35

def describe_db_parameter_groups(name=nil, opts={})
  response = Excon::Response.new
  parameter_set = []
  if name
    if server = self.data[:parameter_groups][name]
      parameter_set << server
    else
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{name} not found")
    end
  else
    parameter_set = self.data[:parameter_groups].values
  end

  response.status = 200
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "DescribeDBParameterGroupsResult" => { "DBParameterGroups" => parameter_set }
  }
  response
end

#describe_db_parameters(name, opts = {}) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/fog/aws/requests/rds/describe_db_parameters.rb', line 36

def describe_db_parameters(name, opts={})
  group = self.data[:parameter_groups][name]

  unless group
    raise Fog::AWS::RDS::NotFound.new("parameter group does not exist")
  end

  parameters = group[:parameters]

  response = Excon::Response.new
  response.body = {
    "ResponseMetadata"           => { "RequestId"  => Fog::AWS::Mock.request_id },
    "DescribeDBParametersResult" => { "Parameters" => parameters }
  }
  response.status = 200
  response
end

#describe_db_reserved_instances(identifier = nil, opts = {}) ⇒ Object



32
33
34
# File 'lib/fog/aws/requests/rds/describe_db_reserved_instances.rb', line 32

def describe_db_reserved_instances(identifier=nil, opts={})
  Fog::Mock.not_implemented
end

#describe_db_security_groups(opts = {}) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fog/aws/requests/rds/describe_db_security_groups.rb', line 28

def describe_db_security_groups(opts={})
  response = Excon::Response.new
  sec_group_set = []
  if opts.is_a?(String)
    sec_group_name = opts
    if sec_group = self.data[:security_groups][sec_group_name]
      sec_group_set << sec_group
    else
      raise Fog::AWS::RDS::NotFound.new("Security Group #{sec_group_name} not found")
    end
  else
    sec_group_set = self.data[:security_groups].values
  end

  # TODO: refactor to not delete items that we're iterating over. Causes
  # model tests to fail (currently pending)
  sec_group_set.each do |sec_group|
    sec_group["IPRanges"].each do |iprange|
      if iprange["Status"] == "authorizing" || iprange["Status"] == "revoking"
        iprange[:tmp] ||= Time.now + Fog::Mock.delay * 2
        if iprange[:tmp] <= Time.now
          iprange["Status"] = "authorized" if iprange["Status"] == "authorizing"
          iprange.delete(:tmp)
          sec_group["IPRanges"].delete(iprange) if iprange["Status"] == "revoking"
        end
      end
    end

    # TODO: refactor to not delete items that we're iterating over. Causes
    # model tests to fail (currently pending)
    sec_group["EC2SecurityGroups"].each do |ec2_secg|
      if ec2_secg["Status"] == "authorizing" || ec2_secg["Status"] == "revoking"
        ec2_secg[:tmp] ||= Time.now + Fog::Mock.delay * 2
        if ec2_secg[:tmp] <= Time.now
          ec2_secg["Status"] = "authorized" if ec2_secg["Status"] == "authorizing"
          ec2_secg.delete(:tmp)
          sec_group["EC2SecurityGroups"].delete(ec2_secg) if ec2_secg["Status"] == "revoking"
        end
      end
    end
  end

  response.status = 200
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "DescribeDBSecurityGroupsResult" => { "DBSecurityGroups" => sec_group_set }
  }
  response
end

#describe_db_snapshots(opts = {}) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/fog/aws/requests/rds/describe_db_snapshots.rb', line 34

def describe_db_snapshots(opts={})
  response = Excon::Response.new
  snapshots = self.data[:snapshots].values
  if opts[:identifier]
    snapshots = snapshots.select { |snapshot| snapshot['DBInstanceIdentifier'] == opts[:identifier] }

  end

  if opts[:snapshot_id]
    snapshots = snapshots.select { |snapshot| snapshot['DBSnapshotIdentifier'] == opts[:snapshot_id] }
    raise Fog::AWS::RDS::NotFound.new("DBSnapshot #{opts[:snapshot_id]} not found") if snapshots.empty?
  end

  snapshots.each do |snapshot|
    case snapshot['Status']
    when 'creating'
      if Time.now - snapshot['SnapshotCreateTime'] > Fog::Mock.delay
        snapshot['Status'] = 'available'
      end
    end
  end

  # Build response
  response.status = 200
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "DescribeDBSnapshotsResult" => { "DBSnapshots" => snapshots }
  }
  response
end

#describe_db_subnet_groups(name = nil, opts = {}) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/fog/aws/requests/rds/describe_db_subnet_groups.rb', line 35

def describe_db_subnet_groups(name = nil, opts = {})
  response = Excon::Response.new

  subnet_group_set = []
  if name
    if subnet_group = self.data[:subnet_groups][name]
      subnet_group_set << subnet_group
    else
      raise Fog::AWS::RDS::NotFound.new("Subnet Group #{name} not found")
    end
  else
    subnet_group_set = self.data[:subnet_groups].values
  end

  response.status = 200
  response.body = {
    "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
    "DescribeDBSubnetGroupsResult" => { "DBSubnetGroups" => subnet_group_set }
  }
  response
end

#describe_engine_default_parameters(family, opts = {}) ⇒ Object



27
28
29
30
31
32
33
34
35
36
# File 'lib/fog/aws/requests/rds/describe_engine_default_parameters.rb', line 27

def describe_engine_default_parameters(family, opts={})
  response = Excon::Response.new

  response.status = 200
  response.body   = {
    "ResponseMetadata"                      => { "RequestId"  => Fog::AWS::Mock.request_id },
    "DescribeEngineDefaultParametersResult" => { "Parameters" => self.data[:default_parameters]}
  }
  response
end

#describe_event_subscriptions(options = {}) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/fog/aws/requests/rds/describe_event_subscriptions.rb', line 29

def describe_event_subscriptions(options={})
  response = Excon::Response.new
  name     = options['SubscriptionName']

  subscriptions = self.data[:event_subscriptions].values
  subscriptions = subscriptions.select { |s| s['CustSubscriptionId'] == name } if name

  non_active = self.data[:event_subscriptions].values.select { |s| s['Status'] != 'active' }

  non_active.each do |s|
    name = s['CustSubscriptionId']
    if s['Status'] == 'creating'
      s['Status'] = 'active'
      self.data[:event_subscriptions][name] = s
    elsif s['Status'] == 'deleting'
      self.data[:event_subscriptions].delete(name)
    end
  end

  if options['SubscriptionName'] && subscriptions.empty?
    raise Fog::AWS::RDS::NotFound.new("Event Subscription #{options['SubscriptionName']} not found.")
  end

  response.body = {
    "ResponseMetadata" => {"RequestId" => Fog::AWS::Mock.request_id},
    "DescribeEventSubscriptionsResult" => {"EventSubscriptionsList" => subscriptions}
  }
  response
end

#describe_eventsObject



44
45
46
# File 'lib/fog/aws/requests/rds/describe_events.rb', line 44

def describe_events
  Fog::Mock.not_implemented
end

#describe_orderable_db_instance_options(engine = nil, opts = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/fog/aws/requests/rds/describe_orderable_db_instance_options.rb', line 39

def describe_orderable_db_instance_options(engine=nil, opts={})
  instance_options = []
  response = Excon::Response.new
  if engine
    (opts[:db_instance_class] || %w(db.m2.xlarge db.m1.large)).each do |size|
      instance_options << {'MultiAZCapable' => true,
                           'Engine' => engine,
                           'LicenseModel' => opts[:license_model] || 'general-public-license',
                           'ReadReplicaCapable' => true,
                           'EngineVersion' => opts[:engine_version] || '5.6.12',
                           'AvailabilityZones' => [
                              {'Name' => 'us-east-1b'},
                              {'Name' => 'us-east-1c'},
                              {'Name' => 'us-east-1d'},
                              {'Name' => 'us-east-1e'}],
                           'DBInstanceClass' => size,
                           'SupportsStorageEncryption' => true,
                           'SupportsPerformanceInsights' => false,
                           'StorageType' => 'gp2',
                           'SupportsIops' => false,
                           'SupportsIAMDatabaseAuthentication' => false,
                           'SupportsEnhancedMonitoring' => true,
                           'Vpc' => opts[:vpc].nil? ? true : opts[:vpc]}

    end
  else
    raise Fog::AWS::RDS::NotFound.new('An engine must be specified to retrieve orderable instance options')
  end

  response.status = 200
  response.body = {
      'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id },
      'DescribeOrderableDBInstanceOptionsResult' => { 'OrderableDBInstanceOptions' => instance_options }
  }
  response
end

#download_db_logfile_portion(identifier = nil, filename = nil, opts = {}) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/fog/aws/requests/rds/download_db_logfile_portion.rb', line 35

def download_db_logfile_portion(identifier=nil, filename=nil, opts={})
  response = Excon::Response.new
  server_set = []
  if identifier
    if server = self.data[:servers][identifier]
      server_set << server
    else
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{identifier} not found")
    end
  else
    server_set = self.data[:servers].values
  end

  response.status = 200
  response.body = {
      "ResponseMetadata" => { "RequestId"=> Fog::AWS::Mock.request_id },
      "DescribeDBInstancesResult" => { "DBInstances" => server_set }
  }
  response
end

#list_tags_for_resource(rds_id) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fog/aws/requests/rds/list_tags_for_resource.rb', line 27

def list_tags_for_resource(rds_id)
  response = Excon::Response.new
  if server = data[:servers][rds_id]
    response.status = 200
    response.body = {
      'ListTagsForResourceResult' =>
        { 'TagList' => data[:tags][rds_id] }
    }
    response
  else
    raise Fog::AWS::RDS::NotFound, "DBInstance #{rds_id} not found"
  end
end

#modify_db_instance(db_name, apply_immediately, _options = {}) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/fog/aws/requests/rds/modify_db_instance.rb', line 49

def modify_db_instance(db_name, apply_immediately, _options={})
  options = _options.dup
  response = Excon::Response.new
  if server = self.data[:servers][db_name]
    if server["DBInstanceStatus"] != "available"
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{db_name} not available for modification")
    else
      self.data[:modify_time] = Time.now
      # TODO verify the params options
      # if apply_immediately is false, all the options go to pending_modified_values and then apply and clear after either
      # a reboot or the maintainance window
      #if apply_immediately
      #  modified_server = server.merge(options)
      #else
      #  modified_server = server["PendingModifiedValues"].merge!(options) # it appends
      #end
      if options["NewDBInstanceIdentifier"]
        options["DBInstanceIdentifier"] = options.delete("NewDBInstanceIdentifier")
        options["Endpoint"]             = {"Port" => server["Endpoint"]["Port"], "Address"=> Fog::AWS::Mock.rds_address(options["DBInstanceIdentifier"],region)}
      end

      rds_security_groups = self.data[:security_groups].values
      ec2_security_groups = Fog::AWS::Compute::Mock.data[@region][@aws_access_key_id][:security_groups].values

      db_security_group_names = Array(options.delete("DBSecurityGroups"))
      db_security_groups = db_security_group_names.inject([]) do |r, group_name|
        unless rds_security_groups.find { |sg| sg["DBSecurityGroupName"] == group_name }
          raise Fog::AWS::RDS::Error.new("InvalidParameterValue => Invalid security group , groupId= , groupName=#{group_name}")
        end
        r << {"Status" => "active", "DBSecurityGroupName" => group_name }
      end

      vpc_security_groups = Array(options.delete("VpcSecurityGroups")).inject([]) do |r, group_id|
        unless ec2_security_groups.find { |sg| sg["groupId"] == group_id }
          raise Fog::AWS::RDS::Error.new("InvalidParameterValue => Invalid security group , groupId=#{group_id} , groupName=")
        end

        r << {"Status" => "active", "VpcSecurityGroupId" => group_id }
      end

      options.merge!(
        "DBSecurityGroups"  => db_security_groups,
        "VpcSecurityGroups" => vpc_security_groups
      )

      self.data[:servers][db_name]["PendingModifiedValues"].merge!(options) # it appends
      self.data[:servers][db_name]["DBInstanceStatus"] = "modifying"
      response.status = 200
      response.body = {
        "ResponseMetadata"       => { "RequestId"  => Fog::AWS::Mock.request_id },
        "ModifyDBInstanceResult" => { "DBInstance" => self.data[:servers][db_name] }
      }
      response

    end
  else
    raise Fog::AWS::RDS::NotFound.new("DBInstance #{db_name} not found")
  end
end

#modify_db_parameter_group(group_name, parameters) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/fog/aws/requests/rds/modify_db_parameter_group.rb', line 44

def modify_db_parameter_group(group_name, parameters)
  group = self.data[:parameter_groups][group_name]

  unless group
    raise Fog::AWS::RDS::NotFound.new("Parameter group not found")
  end

  parameters.each do |p|
    p.merge!(
      "Source"        => "user",
      "IsModifiable"  => true,
      "Description"   => "some string",
      "DataType"      => "string",
      "AllowedValues" => p["ParameterValue"],
      "ApplyType"     => "dynamic"
    )
  end

  group[:parameters] = parameters

  self.data[:parameter_groups][group_name] = group

  response = Excon::Response.new
  response.body = {
    "ResponseMetadata"             => {"RequestId"            => Fog::AWS::Mock.request_id},
    "ModifyDBParameterGroupResult" => {"DBParameterGroupName" => group_name}
  }
  response.status = 200
  response
end

#modify_db_snapshot_attribute(db_snapshot_identifier, attributes) ⇒ Object

Usage

Fog::AWS.modify_db_snapshot_attribute(“snap-identifier”, Fog::AWS::RDS::Mock.“Add“Add.MemberId”=>“389480430104”)



37
38
39
40
41
42
43
44
# File 'lib/fog/aws/requests/rds/modify_db_snapshot_attribute.rb', line 37

def modify_db_snapshot_attribute(db_snapshot_identifier, attributes)
  response = Excon::Response.new
  response.status = 200
  response.body = {
    'requestId' => Fog::AWS::Mock.request_id
  }.merge!(data)
  response
end

#promote_read_replica(identifier, backup_retention_period = nil, preferred_backup_window = nil) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fog/aws/requests/rds/promote_read_replica.rb', line 36

def promote_read_replica(identifier, backup_retention_period = nil, preferred_backup_window = nil)
  server = self.data[:servers][identifier]
  server || raise(Fog::AWS::RDS::NotFound.new("DBInstance #{identifier} not found"))

  if server["ReadReplicaSourceDBInstanceIdentifier"].nil?
    raise(Fog::AWS::RDS::Error.new("InvalidDBInstanceState => DB Instance is not a read replica."))
  end

  self.data[:modify_time] = Time.now

  data = {
    'BackupRetentionPeriod' => backup_retention_period || 1,
    'PreferredBackupWindow' => preferred_backup_window || '08:00-08:30',
    'DBInstanceIdentifier'  => identifier,
    'DBInstanceStatus'      => "modifying",
    'PendingModifiedValues' => {
      'ReadReplicaSourceDBInstanceIdentifier' => nil,
    }
  }

  server.merge!(data)

  response = Excon::Response.new
  response.body = {
    "ResponseMetadata"         => { "RequestId"  => Fog::AWS::Mock.request_id },
    "PromoteReadReplicaResult" => { "DBInstance" => server }
  }
  response.status = 200
  response
end

#reboot_db_instance(instance_identifier) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/fog/aws/requests/rds/reboot_db_instance.rb', line 24

def reboot_db_instance(instance_identifier)
  response = Excon::Response.new
  if server = self.data[:servers][instance_identifier]
    if server["DBInstanceStatus"] != "available"
      raise Fog::AWS::RDS::NotFound.new("DBInstance #{instance_identifier} not available for rebooting")
    else
      server["DBInstanceStatus"] = 'rebooting'
      self.data[:reboot_time] = Time.now
      response.status = 200
      response.body = {
        "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
        "RebootDBInstanceResult" => { "DBInstance" => server }
      }
      response

    end
  else
    raise Fog::AWS::RDS::NotFound.new("DBInstance #{instance_identifier} not found")
  end
end

#remove_tags_from_resource(rds_id, keys) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/fog/aws/requests/rds/remove_tags_from_resource.rb', line 25

def remove_tags_from_resource(rds_id, keys)
  response = Excon::Response.new
  if server = data[:servers][rds_id]
    keys.each { |key| data[:tags][rds_id].delete key }
    response.status = 200
    response.body = {
      'ResponseMetadata' => { 'RequestId' => Fog::AWS::Mock.request_id }
    }
    response
  else
    raise Fog::AWS::RDS::NotFound, "DBInstance #{rds_id} not found"
  end
end

#reset_dataObject



182
183
184
# File 'lib/fog/aws/rds.rb', line 182

def reset_data
  self.class.data[@region].delete(@aws_access_key_id)
end

#restore_db_instance_from_db_snapshot(snapshot_id, db_name, options = {}) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/fog/aws/requests/rds/restore_db_instance_from_db_snapshot.rb', line 23

def restore_db_instance_from_db_snapshot(snapshot_id, db_name, options={})

  if self.data[:servers] and self.data[:servers][db_name]
    raise Fog::AWS::RDS::IdentifierTaken.new("DBInstanceAlreadyExists #{response.body.to_s}")
  end

  unless self.data[:snapshots] and snapshot = self.data[:snapshots][snapshot_id]
    raise Fog::AWS::RDS::NotFound.new("DBSnapshotNotFound #{response.body.to_s}")
  end

  if !!options["MultiAZ"] && !!options["AvailabilityZone"]
    raise Fog::AWS::RDS::InvalidParameterCombination.new('Requesting a specific availability zone is not valid for Multi-AZ instances.')
  end

  option_group_membership =
    if option_group_name = options['OptionGroupName']
      [{ 'OptionGroupMembership' =>
        [{ 'OptionGroupName' => option_group_name, 'Status' => "pending-apply"}] }]
    else
      [{ 'OptionGroupMembership' =>
        [{ 'OptionGroupName' => 'default: mysql-5.6', 'Status' => "pending-apply"}] }]
    end

  data = {
    "AllocatedStorage"                 => snapshot['AllocatedStorage'],
    "AutoMinorVersionUpgrade"          => options['AutoMinorVersionUpgrade'].nil? ? true : options['AutoMinorVersionUpgrade'],
    "AvailabilityZone"                 => options['AvailabilityZone'],
    "BackupRetentionPeriod"            => options['BackupRetentionPeriod'] || 1,
    "CACertificateIdentifier"          => 'rds-ca-2015',
    "DBInstanceClass"                  => options['DBInstanceClass'] || 'db.m3.medium',
    "DBInstanceIdentifier"             => db_name,
    "DBInstanceStatus"                 => 'creating',
    "DBName"                           => options['DBName'],
    "DBParameterGroups"                => [{'DBParameterGroupName'=>'default.mysql5.5', 'ParameterApplyStatus'=>'in-sync'}],
    "DBSecurityGroups"                 => [{'Status'=>'active', 'DBSecurityGroupName'=>'default'}],
    "Endpoint"                         => {},
    "Engine"                           => options['Engine'] || snapshot['Engine'],
    "EngineVersion"                    => options['EngineVersion'] || snapshot['EngineVersion'],
    "InstanceCreateTime"               => nil,
    "Iops"                             => options['Iops'],
    "LicenseModel"                     => options['LicenseModel'] || snapshot['LicenseModel'] || 'general-public-license',
    "MasterUsername"                   => options['MasterUsername'] || snapshot['MasterUsername'],
    "MultiAZ"                          => !!options['MultiAZ'],
    "OptiongroupMemberships"           => option_group_membership,
    "PendingModifiedValues"            => { 'MasterUserPassword' => '****' }, # This clears when is available
    "PreferredBackupWindow"            => '08:00-08:30',
    "PreferredMaintenanceWindow"       => 'mon:04:30-mon:05:00',
    "PubliclyAccessible"               => true,
    "ReadReplicaDBInstanceIdentifiers" => [],
    "StorageType"                      => options['StorageType'] || (options['Iops'] ? 'io1' : 'standard'),
    "VpcSecurityGroups"                => nil,
    "StorageEncrypted"                 => false,
  }

  self.data[:servers][db_name] = data
  response = Excon::Response.new
  response.body =
    { "ResponseMetadata" => { "RequestId" => Fog::AWS::Mock.request_id },
      "RestoreDBInstanceFromDBSnapshotResult" => { "DBInstance" => data }
  }
  response.status = 200
  self.data[:servers][db_name]["InstanceCreateTime"] = Time.now
  response
end

#restore_db_instance_to_point_in_time(source_db_name, target_db_name, opts = {}) ⇒ Object



23
24
25
# File 'lib/fog/aws/requests/rds/restore_db_instance_to_point_in_time.rb', line 23

def restore_db_instance_to_point_in_time(source_db_name, target_db_name, opts={})
  Fog::Mock.not_implemented
end

#revoke_db_security_group_ingress(name, opts = {}) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/fog/aws/requests/rds/revoke_db_security_group_ingress.rb', line 31

def revoke_db_security_group_ingress(name, opts = {})
  unless opts.key?('CIDRIP') || ((opts.key?('EC2SecurityGroupName') || opts.key?('EC2SecurityGroupId')) && opts.key?('EC2SecurityGroupOwnerId'))
    raise ArgumentError, 'Must specify CIDRIP, or one of EC2SecurityGroupName or EC2SecurityGroupId, and EC2SecurityGroupOwnerId'
  end

  if ec2_security_group_id = opts.delete("EC2SecurityGroupId")
    ec2_security_group = (Fog::AWS::Compute::Mock.data[self.region][self.aws_access_key_id][:security_groups] || {}).values.detect { |sg| sg['groupId'] == ec2_security_group_id }
    opts['EC2SecurityGroupName'] = ec2_security_group['groupName']
  end

  response = Excon::Response.new

  if sec_group = self.data[:security_groups][name]
    if opts.key?('CIDRIP')
      sec_group['IPRanges'].each do |iprange|
        iprange['Status']= 'revoking' if iprange['CIDRIP'] == opts['CIDRIP']
      end
    else
      sec_group['EC2SecurityGroups'].each do |ec2_secg|
        ec2_secg['Status']= 'revoking' if ec2_secg['EC2SecurityGroupName'] == opts['EC2SecurityGroupName']
      end
    end
    response.status = 200
    response.body = {
      "ResponseMetadata"=>{ "RequestId"=> Fog::AWS::Mock.request_id },
      'RevokeDBSecurityGroupIngressResult' => {
        'DBSecurityGroup' => sec_group
      }
    }
    response
  else
    raise Fog::AWS::RDS::NotFound.new("DBSecurityGroupNotFound => #{name} not found")
  end
end

#setup_credentials(options) ⇒ Object



186
187
188
# File 'lib/fog/aws/rds.rb', line 186

def setup_credentials(options)
  @aws_access_key_id = options[:aws_access_key_id]
end