Class: Mondupe

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

Instance Method Summary collapse

Instance Method Details

#add_user(instance_ip, username, password, database, roles) ⇒ Object



131
132
133
# File 'lib/mondupe.rb', line 131

def add_user(instance_ip, username, password, database, roles)
  #add db users here
end

#bootstrap(instance_name, instance_fqdn, instance_ip, chef_environment, chef_run_list, ssh_key, ssh_user, knife_exec) ⇒ Object



107
108
109
110
111
112
113
114
115
116
# File 'lib/mondupe.rb', line 107

def bootstrap(instance_name, instance_fqdn, instance_ip, chef_environment, chef_run_list, ssh_key, ssh_user, knife_exec)
  # Bootstrap the new instance with chef
  puts "Bootstraping node with Chef..."
  puts "Running..."
  #puts "#{knife_exec} bootstrap #{instance_ipaddress} -N #{instance_fqdn[0...-1]} -E #{chef_environment} -i #{chef_identity_file} -r #{chef_run_list} -x #{ssh_user} --sudo"
  result = try_command(20, 20, "ssh -i #{ssh_key} #{ssh_user}@#{instance_ip} \"date\"")
  puts "Try SSH Result: #{result}"
  result = system("#{knife_exec} bootstrap #{instance_ip} -N #{instance_fqdn[0...-1]} -E #{chef_environment} -i #{ssh_key} -r #{chef_run_list} -x #{ssh_user} --sudo") or abort "Knife bootstrap failed"
  puts "System Knife Result: #{result}"
end

#create_dns(instance_fqdn, route53_domain, instance) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/mondupe.rb', line 69

def create_dns(instance_fqdn, route53_domain, instance)
  # Set up DNS through Route53
  puts "Setting up Route53 DNS..."

  # Check to see if record exists
  route53 = AWS::Route53.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
  zone = route53.hosted_zones.select { |z| z.name == route53_domain }.first
  rrsets = AWS::Route53::HostedZone.new(zone.id).rrsets
  rrset = rrsets[instance_fqdn, 'CNAME']

  if rrset.exists?
    # Update if record exists
    rrset.resource_records = [ { :value => instance.dns_name } ]
    rrset.update
    puts "Updated CNAME '#{instance_fqdn}' to point to '#{instance.dns_name}'"
  else
    # Create new record if does not exist
    rrset = rrsets.create(instance_fqdn, 'CNAME', :ttl => 300, :resource_records => [{:value => instance.dns_name }])
    puts "Added CNAME '#{instance_fqdn}' pointing to '#{instance.dns_name}'"
  end
end

#create_instance(instance_name, instance_image_id, instance_type, instance_count, security_group, key_pair_name, expire_days, instance_owner, instance_volume_size) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
# File 'lib/mondupe.rb', line 6

def create_instance(instance_name, instance_image_id, instance_type, instance_count, security_group, key_pair_name, expire_days, instance_owner, instance_volume_size)
  #AWS.config(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'], region: 'us-east-1')

  ec2 = AWS::EC2.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
  key_pair = ec2.key_pairs[key_pair_name]

  # Use this to create a new security group - Can have preset options
  #security_group = ec2.security_groups.create("sg_#{instance_name}")
  #security_group = 'sg_my_awesome_new_instance'

  instance = ec2.instances.create(
    :image_id => instance_image_id,
    :block_device_mappings => [{
      :device_name => "/dev/sda1",
      :ebs => {
        :volume_size => instance_volume_size,
        :delete_on_termination => true
      }
    }],
    :instance_type => instance_type,
    :count => instance_count,
    :security_groups => [ security_group ],
    :key_pair => key_pair
  )

  created_date_time = Time.now.to_i

  # Display some information about the new instance
  puts "Instance '#{instance_name}' created with ID '#{instance.id}'"

  instance.tag('Name', :value => instance_name)
  instance.tag('owner', :value => instance_owner)
  instance.tag('expire_days', :value => expire_days)
  instance.tag('created', :value => created_date_time)
  instance.tag('mondupe')

  puts "Added tags... "
  puts "  Name: #{instance_name}"
  puts "  owner: #{instance_owner}"
  puts "  expires: #{expire_days}"
  puts "  created: #{created_date_time}"

  # Wait for instance to be ready
  current_state = ""
  until instance.status == :running
    if current_state != instance.status
      puts "Status: #{instance.status.to_s}"
      print "Instance coming up "
      current_state = instance.status
    else
      print "."
      sleep 1
    end
  end

  puts ""
  puts "Instance #{instance.id} is now running"
  puts "Name: #{instance.tags['Name']}"
  puts "IP: #{instance.ip_address}"
  puts "Public DNS: #{instance.dns_name}"
  instance
end

#execute_js(instance_dns, ssh_key, ssh_user, java_command, mongo_db_name, mongo_user, mongo_pass, mongo_auth_db) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/mondupe.rb', line 161

def execute_js(instance_dns, ssh_key, ssh_user, java_command, mongo_db_name, mongo_user, mongo_pass, mongo_auth_db)
  abort "You must specify a database name to execute java script against. Use -r [mongo_db_name] or ENV['MONGO_DB_NAME'] to set this value." if mongo_db_name.nil?
  db_connect_string = "mongo #{mongo_db_name}"
  db_connect_string << " -u \"#{mongo_user}\" -p \"#{mongo_pass}\"" if !mongo_user.nil? && !mongo_pass.nil?
  db_connect_string << " --authenticationDatabase \"#{mongo_auth_db}\"" if !mongo_auth_db.nil?
  #puts "Connect String: #{db_connect_string}"
  puts "#{Time.now.to_s} - Running command on #{instance_dns} against #{mongo_db_name}"
  puts "JS Query: #{java_command}"
  db_output = try_command(20, 20, "ssh -i #{ssh_key} #{ssh_user}@#{instance_dns} \"#{db_connect_string} --eval '#{java_command}'\"") or abort "Failed to run command"
  puts db_output
  if $?.success? then puts "#{Time.now.to_s} - Command execution complete" else abort("Error executing command") end
end

#expire(instance_id, instance_name, expire_days) ⇒ Object



182
183
184
# File 'lib/mondupe.rb', line 182

def expire(instance_id, instance_name, expire_days)
  puts "function not quite ready yet"
end

#get_db_dump_from_s3(instance_ip, s3_bucket_name, dump_tmp_path, ssh_key, ssh_user, dump_file_name) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/mondupe.rb', line 118

def get_db_dump_from_s3(instance_ip, s3_bucket_name, dump_tmp_path, ssh_key, ssh_user, dump_file_name)
  expiration = Time.now.to_i + 400*60
  s3 = AWS::S3.new(:access_key_id => ENV['AWS_ACCESS_KEY_ID'], :secret_access_key => ENV['AWS_SECRET_ACCESS_KEY'])
  backups = s3.buckets[s3_bucket_name]
  latest_backup = backups.objects.sort_by {|backup| backup.last_modified}.last
  download_url = latest_backup.url_for(:get, :expires_in => expiration, :response_content_type => "application/json")
  puts "Download URL: #{download_url}"
  puts "#{Time.now.to_s} - Starting download."
  puts "  Please wait..."
  `ssh -i #{ssh_key} #{ssh_user}@#{instance_ip} "sudo mkdir -p #{dump_tmp_path} && sudo chown #{ssh_user}:#{ssh_user} #{dump_tmp_path} && cd #{dump_tmp_path} && wget '#{download_url}' -O #{File.join(dump_tmp_path, dump_file_name)} 2&>1"`
  puts "#{Time.now.to_s} - Download completed"
end

#listObject



178
179
180
# File 'lib/mondupe.rb', line 178

def list
  puts "function not quite ready yet"
end

#restore_db(instance_ip, dump_tmp_path, ssh_key, ssh_user, dump_file_name, mongo_db_name, mongo_user, mongo_pass, mongo_auth_db) ⇒ Object



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
# File 'lib/mondupe.rb', line 135

def restore_db(instance_ip, dump_tmp_path, ssh_key, ssh_user, dump_file_name, mongo_db_name, mongo_user, mongo_pass, mongo_auth_db)
  # Restore from the database dump
  # TODO - Fail the process if any step fails
  abort "You must specify a database name to drop and restore. Use -n [name] or ENV['MONGO_DB_NAME'] to set this value." if mongo_db_name.nil?
  ssh_command = "ssh -i #{ssh_key} #{ssh_user}@#{instance_ip}"
  db_connect_string = "mongo #{mongo_db_name}"
  db_connect_string << " -u \"#{mongo_user}\" -p \"#{mongo_pass}\"" if !mongo_user.nil? && !mongo_pass.nil?
  db_connect_string << " --authenticationDatabase \"#{mongo_auth_db}\"" if !mongo_auth_db.nil?
  try_command(20, 20, "#{ssh_command} \"echo 'db.serverStatus()' | #{db_connect_string}\"") or abort "Failed to connect"
  puts "#{Time.now.to_s} - Dropping existing database"
  `#{ssh_command} "#{db_connect_string} --eval 'db.dropDatabase()'"`
  if $?.success? then puts "#{Time.now.to_s} - Database drop complete" else abort("Error dropping database") end
  puts "Extracting database dump archive file..."
  `#{ssh_command} "cd #{dump_tmp_path}; tar xf #{dump_file_name}"`
  if $?.success? then puts "#{Time.now.to_s} - Extraction complete!" else abort("Error extracting archive") end
  puts "Restoring Mongo Database from extracted dump: #{File.join(dump_tmp_path, "#{mongo_db_name}")}"
  `#{ssh_command} "time mongorestore #{File.join(dump_tmp_path, "#{mongo_db_name}")}"`
  if $?.success? then puts "#{Time.now.to_s} - Database restore complete!" else abort("Error restoring databse") end
  puts "Removing database archive file"
  `#{ssh_command} "rm -rf #{File.join(dump_tmp_path, dump_file_name)}"`
  if $?.success? then puts "#{Time.now.to_s} - Archive removed!" else abort("Error removing archive") end
  puts "#{Time.now.to_s} - Cleaning up our mess..."
  `#{ssh_command} "rm -rf #{File.join(dump_tmp_path, "#{mongo_db_name}")}"`
  if $?.success? then puts "#{Time.now.to_s} - Mess cleaned up!" else abort("Error cleaning up after myself...") end
end

#terminate(instance_id) ⇒ Object



174
175
176
# File 'lib/mondupe.rb', line 174

def terminate(instance_id)
  puts "function not quite ready yet"
end

#try_command(tries, wait, command) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/mondupe.rb', line 91

def try_command(tries, wait, command)
  begin
    `#{command}`
    result = $?.success? or raise "ERROR"
  rescue
    tries -= 1
    if tries > 0
      puts "Trying again. #{tries} left."
      sleep wait
      retry
    end
    puts "Failed after #{tries} retries..."
    return result
  end
end