Class: Cucloud::RdsUtils

Inherits:
Object
  • Object
show all
Defined in:
lib/cucloud/rds_utils.rb

Overview

RdsUtils class - for interacting with the AWS relational database service

Defined Under Namespace

Classes: RDSInstanceAlreadyExist

Instance Method Summary collapse

Constructor Details

#initialize(rds_client = Aws::RDS::Client.new) ⇒ RdsUtils

Returns a new instance of RdsUtils.



9
10
11
# File 'lib/cucloud/rds_utils.rb', line 9

def initialize(rds_client = Aws::RDS::Client.new)
  @rds = rds_client
end

Instance Method Details

#create_snapshot_and_wait_until_available(rds_instance, tags = []) ⇒ Aws::RDS::DBSnapshot

Create a new snapshot of the instance, if no snapshots are already in the process of being created, and wait indefinitely until the snapshot is complete.

Parameters:

  • rds_instance (Aws::RDS::DBInstance)

    the RDS instance which to snapshot

  • tags (Array<Hash>) (defaults to: [])

    tags to assign to the snapshot; each array element should be of the form { key: "some key", value: "some value" }

Returns:

  • (Aws::RDS::DBSnapshot)

    handle to the new snapshot; nil if a new snapshot cannot be created because of other pending snapshots



171
172
173
174
175
# File 'lib/cucloud/rds_utils.rb', line 171

def create_snapshot_and_wait_until_available(rds_instance, tags = [])
  return nil unless pending_snapshots(rds_instance).empty?
  snap = start_snapshot(rds_instance, tags)
  wait_until_snapshot_available(snap, nil, 10)
end

#delete_db_instance(db_instance_identifier, db_snapshot_identifier = nil) ⇒ Object

Delete a givne db instance

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

  • db_snapshot_identifier (String) (defaults to: nil)

    Name for final snapshot, default is nil



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/cucloud/rds_utils.rb', line 34

def delete_db_instance(db_instance_identifier, db_snapshot_identifier = nil)
  unless does_db_exist?(db_instance_identifier)
    raise Aws::RDS::Errors::DBInstanceNotFound.new(
      db_instance_identifier,
      ''
    )
  end

  if db_snapshot_identifier.nil?
    @rds.delete_db_instance(db_instance_identifier: db_instance_identifier, skip_final_snapshot: true)
  else
    @rds.delete_db_instance(db_instance_identifier: db_instance_identifier,
                            final_db_snapshot_identifier: db_snapshot_identifier)
  end

  @rds.wait_until(:db_instance_deleted, db_instance_identifier: db_instance_identifier)
end

#does_db_exist?(db_instance_identifier) ⇒ boolean

Determine if a givne db instance exist

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

Returns:

  • (boolean)


24
25
26
27
28
29
# File 'lib/cucloud/rds_utils.rb', line 24

def does_db_exist?(db_instance_identifier)
  get_instance(db_instance_identifier).instance_create_time
  true
rescue
  false
end

#find_latest_snapshot(db_instance_identifier, snapshot_type = 'manual') ⇒ String

Find the latest snapshot for a given RDS instance

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

  • snapshot_type (String) (defaults to: 'manual')

    One of the following types public, shared, manual or automated

Returns:

  • (String)

    Most recent snapshot ID for given RDS instance



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/cucloud/rds_utils.rb', line 96

def find_latest_snapshot(db_instance_identifier, snapshot_type = 'manual')
  latest_snapshot_time = Time.new(2002)
  latest_snap_shot = nil
  snapshots_info = @rds.describe_db_snapshots(
    db_instance_identifier: db_instance_identifier, snapshot_type: snapshot_type
  )[:db_snapshots]

  snapshots_info.each do |snapshot_info|
    next if snapshot_info[:status] != 'available'

    if latest_snapshot_time.to_i < snapshot_info[:snapshot_create_time].to_i
      latest_snapshot_time = snapshot_info[:snapshot_create_time].to_i
      latest_snap_shot = snapshot_info
    end
  end

  latest_snap_shot.nil? ? nil : latest_snap_shot[:db_snapshot_identifier]
end

#find_rds_snapshots(options = {}, snapshot_type = 'manual') ⇒ String

Find RDS Snapshot older than supplied days

Parameters:

  • options (Hash) (defaults to: {})

    User specified search options

  • snapshot_type (String) (defaults to: 'manual')

    One of the following types public, shared, manual or automated

Returns:

  • (String)

    Most recent snapshot ID for given RDS instance



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/cucloud/rds_utils.rb', line 181

def find_rds_snapshots(options = {}, snapshot_type = 'manual')
  days_old = options[:days_old]
  found_snap_shots = []

  snapshots_info = @rds.describe_db_snapshots(snapshot_type: snapshot_type)[:db_snapshots]

  snapshots_info.each do |snapshot_info|
    next if snapshot_info[:status] != 'available'
    if !days_old.nil?
      snapshot_days_old = (Time.now.to_i - snapshot_info[:snapshot_create_time].to_i) / Cucloud::SECONDS_IN_A_DAY
      if snapshot_days_old > days_old
        found_snap_shots.push(snapshot_info[:db_snapshot_identifier])
      end
    else
      found_snap_shots.push(snapshot_info[:db_snapshot_identifier])
    end
  end
  found_snap_shots
end

#get_instance(db_instance_identifier) ⇒ Aws::RDS::DBInstance

Get the RDS instance object with the given name

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier (e.g., "jadu-test-dev")

Returns:

  • (Aws::RDS::DBInstance)

    the instance object



16
17
18
19
# File 'lib/cucloud/rds_utils.rb', line 16

def get_instance(db_instance_identifier)
  resource = Aws::RDS::Resource.new(client: @rds)
  resource.db_instance(db_instance_identifier)
end

#modify_db_instance(options) ⇒ Hash

Base function to modify DB, resets defualts for apply_immediately and copy_tags_to_snapshot

Parameters:

  • options (hash)

    Hash represnting the configuration for the RDS modify

Returns:

  • (Hash)

    Hash represnting the return from AWS



71
72
73
74
75
76
# File 'lib/cucloud/rds_utils.rb', line 71

def modify_db_instance(options)
  options[:apply_immediately] = options[:apply_immediately].nil? ? true : options[:apply_immediately]
  options[:copy_tags_to_snapshot] = options[:copy_tags_to_snapshot].nil? ? true : options[:copy_tags_to_snapshot]

  @rds.modify_db_instance(options)
end

#modify_option_group(db_instance_identifier, option_group_name) ⇒ Hash

Modify the options group for a RDS instance

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

  • option_group_name (Sting)

    Name of the options group to apply

Returns:

  • (Hash)

    Hash represnting the return from AWS



64
65
66
# File 'lib/cucloud/rds_utils.rb', line 64

def modify_option_group(db_instance_identifier, option_group_name)
  modify_db_instance(db_instance_identifier: db_instance_identifier, option_group_name: option_group_name)
end

#modify_security_group(db_instance_identifier, vpc_security_groups) ⇒ Hash

Modify the security groups for a RDS instance

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

  • vpc_security_group_ids (Array)

    Array of security groups to apply

Returns:

  • (Hash)

    Hash represnting the return from AWS



56
57
58
# File 'lib/cucloud/rds_utils.rb', line 56

def modify_security_group(db_instance_identifier, vpc_security_groups)
  modify_db_instance(db_instance_identifier: db_instance_identifier, vpc_security_group_ids: vpc_security_groups)
end

#pending_snapshots(rds_instance) ⇒ Collection<Aws::RDS::DBSnapshot>

Return list of pending snapshots for the instance. New snapshots cannot be created if there are any snapshots in the process of being created for the given instance.

Parameters:

  • rds_instance (Aws::RDS::DBInstance)

    the RDS instance to examine

Returns:

  • (Collection<Aws::RDS::DBSnapshot>)

    the collection of snapshots in the process of being created



138
139
140
141
142
143
# File 'lib/cucloud/rds_utils.rb', line 138

def pending_snapshots(rds_instance)
  snaps = rds_instance.snapshots
  snaps.select do |snap|
    snap.status == 'creating'
  end
end

#restore_db(db_instance_identifier, restore_from, options = {}) ⇒ Object

Restore DB from a snapshot

Parameters:

  • db_instance_identifier (String)

    RDS instance identifier

  • db_snapshot_identifier (String)

    Name for final snapshot, default is nil

Raises:



81
82
83
84
85
86
87
88
89
90
# File 'lib/cucloud/rds_utils.rb', line 81

def restore_db(db_instance_identifier, restore_from, options = {})
  raise RDSInstanceAlreadyExist if does_db_exist?(db_instance_identifier)

  db_snapshot_identifier =
    options[:db_snapshot_identifier].nil? ? find_latest_snapshot(restore_from) : options[:db_snapshot_identifier]
  options[:db_instance_identifier] = db_instance_identifier
  options[:db_snapshot_identifier] = db_snapshot_identifier
  @rds.restore_db_instance_from_db_snapshot(options)
  @rds.wait_until(:db_instance_available, db_instance_identifier: db_instance_identifier)
end

#start_snapshot(rds_instance, tags = []) ⇒ Aws::RDS::DBSnapshot

Begins the creation of a snapshot of the given RDS instance. This is a non-blocking call so it will return before the snapshot is created and available.

Parameters:

  • rds_instance (Aws::RDS::DBInstance)

    the RDS instance which to snapshot

  • tags (Array<Hash>) (defaults to: [])

    tags to assign to the snapshot; each array element should be of the form { key: "some key", value: "some value" }

Returns:

  • (Aws::RDS::DBSnapshot)

    handle to the new snapshot



122
123
124
125
126
127
128
129
130
131
# File 'lib/cucloud/rds_utils.rb', line 122

def start_snapshot(rds_instance, tags = [])
  date = Time.new
  snap_id = rds_instance.db_instance_identifier + '-' + date.year.to_s + '-' \
      + zerofill2(date.month) + '-' + zerofill2(date.day) + '-' \
      + zerofill2(date.hour) + '-' + zerofill2(date.min)
  rds_instance.create_snapshot(
    db_snapshot_identifier:  snap_id,
    tags: tags
  )
end

#wait_until_snapshot_available(snapshot, max_attempts = nil, delay = 10) ⇒ Aws::RDS::DBSnapshot

Wait for the completion and availability of a snapshot.

Parameters:

  • snapshot (Aws::RDS::DBSnapshot)

    the snapshot of interest

  • max_attempts (Integer) (defaults to: nil)

    (optional) maximum number of times to poll the snapshot for status updates; defaults to nil which polls indefinitely

  • delay (Integer) (defaults to: 10)

    (optional) number of seconds to delay between polling; defaults to 10

Returns:

  • (Aws::RDS::DBSnapshot)

    snapshot with updated attributes; returns nil if the snapshot did not complete within the allowed time.



153
154
155
156
157
158
159
160
161
# File 'lib/cucloud/rds_utils.rb', line 153

def wait_until_snapshot_available(snapshot, max_attempts = nil, delay = 10)
  snapshot.wait_until(max_attempts: max_attempts, delay: delay) do |snap|
    # Status == available is a conservative test for completion.
    # A more liberal test would be percent_progress == 100.
    snap.status == 'available'
  end
rescue Aws::Waiters::Errors::WaiterFailed
  nil
end