Class: CloudInteractor::Server

Inherits:
Object
  • Object
show all
Defined in:
lib/cloud_interactor/server.rb,
lib/cloud_interactor/server/list.rb,
lib/cloud_interactor/server/poll.rb,
lib/cloud_interactor/server/read.rb,
lib/cloud_interactor/server/create.rb,
lib/cloud_interactor/server/destroy.rb,
lib/cloud_interactor/server/read_volume.rb,
lib/cloud_interactor/server/list_volumes.rb,
lib/cloud_interactor/server/attach_volume.rb,
lib/cloud_interactor/server/detach_volume.rb

Overview

Constant Summary collapse

IDENTITY =
'servers'
RESOURCE =
'compute'

Instance Method Summary collapse

Constructor Details

#initialize(main_obj, classes, options = {}) ⇒ Server



7
8
9
10
11
# File 'lib/cloud_interactor/server.rb', line 7

def initialize main_obj, classes, options={} 
  @main_obj  = main_obj
  @options   = options
  @classes   = classes
end

Instance Method Details

#attach_volume(args) ⇒ Object

handles self and create_and_attach case



4
5
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
# File 'lib/cloud_interactor/server/attach_volume.rb', line 4

def attach_volume args
  @classes['volume'].read args['volume_name'], false

  if @main_obj['specific_volumes'].nil? || @main_obj['specific_volumes'].nil?
    
    create_hash                = { "display_name" => args['volume_name'] }
    create_hash['size']        = args['size'] if args['size']
    create_hash['volume_type'] = args['volume_type'] ? args['volume_type'] : 'SATA'

    @classes['volume'].create create_hash

    sleep 5

    @classes['volume'].read args
  end

  puts "Attaching #{ args['volume_name'] } to #{ args['server_name'] } in #{ IDENTITY }..."

  read args, false, 'name', 'server_name'

  specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).get @main_obj["specific_#{ IDENTITY }"].last['id']

  if args['device_location']
    specific_fog_object.attach_volume @main_obj['specific_volumes'].first['id'], args['device_location']
  else
    specific_fog_object.attach_volume @main_obj['specific_volumes'].first['id']
  end
end

#create(args) ⇒ Object



4
5
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
# File 'lib/cloud_interactor/server/create.rb', line 4

def create args
  @classes['image'].read @options['preferred_cloud_image'], false

  #Note, if no flavor is passed it defaults to a 512MB standard!
  @classes['flavor'].read args['flavor']

  @classes['region'].read(@options['preferred_cloud_region'], false) if @options['preferred_cloud'] == 'digitalocean'
  @classes['sshkey'].bootstrap if @options['preferred_cloud'] == 'digitalocean'

  read args, false

  unless @main_obj["specific_#{ IDENTITY }"].empty?
    puts "#{ IDENTITY } #{ args['name'] } already exists... returning."

    return false
  end

  puts "Creating #{ args['name'] } in #{ IDENTITY }..."

  final_create_args = {
    name:      args['name'],
    flavor_id: @main_obj['specific_flavors'].first['id'],
    image_id:  @main_obj['specific_images'].first['id']
  }

  if @options['preferred_cloud'] == 'digitalocean'
    final_create_args[:region]             = @main_obj['specific_regions'].first['slug']
    final_create_args[:ssh_keys]           = [@main_obj['specific_ssh_keys'].first['id']]
    final_create_args[:size]               = @main_obj['specific_flavors'].first['slug']
    final_create_args[:image]              = @main_obj['specific_images'].first['slug']
    final_create_args[:private_networking] = true

    final_create_args.delete(:flavor_id)
    final_create_args.delete(:image_id)
  end

  @main_obj["#{ IDENTITY }_create_request"] = JSON.parse(@classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).create(final_create_args).to_json)

  @main_obj["#{ IDENTITY }_created_passwords"] ||= {}
  @main_obj["#{ IDENTITY }_created_passwords"][args['name']] = @main_obj["#{ IDENTITY }_create_request"]['password']

  @main_obj["#{ IDENTITY }_created_details"] ||= {}
  @main_obj["#{ IDENTITY }_created_details"][args['name']] = @main_obj["#{ IDENTITY }_create_request"]

  puts "Successfully created #{ args['name'] } with pass #{ @main_obj["#{ IDENTITY }_created_passwords"][args['name']] }"

  @main_obj['output']['admin_passwords'] = { args['name'] => @main_obj["#{ IDENTITY }_created_passwords"][args['name']] }
end

#destroy(args) ⇒ Object



3
4
5
6
7
8
9
# File 'lib/cloud_interactor/server/destroy.rb', line 3

def destroy args
  read args, false

  #TODO strict checking on servers to ensure a server can't be destroyed while it still has volumes attached (which can corrupt the volume)

  @classes['helper'].generic_destroy_parse args, IDENTITY, RESOURCE
end

#detach_volume(args, out = "") ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/cloud_interactor/server/detach_volume.rb', line 3

def detach_volume args, out=""
  read args, false, 'name', 'server_name'

  read_volume args, false, true

  puts "Detaching #{ args['volume_name'] } from #{ args['server_name'] } in #{ IDENTITY }..."

  specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).get @main_obj["specific_#{ IDENTITY }"].last['id']

  specific_fog_object.attachments.each do |attachment|
    next unless attachment.volume_id == @main_obj["specific_attached_volumes"].first['id']
    
    out << attachment.detach.to_s
  end

  puts "The state of the volume detachment is #{ out } for #{ args['server_name'] } in #{ IDENTITY }"
end

#list(args = {}, output = true) ⇒ Object



3
4
5
# File 'lib/cloud_interactor/server/list.rb', line 3

def list args={}, output=true
  @classes['helper'].generic_list_call IDENTITY, RESOURCE, output
end

#list_volumes(args, output = true) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/cloud_interactor/server/list_volumes.rb', line 3

def list_volumes args, output=true
  puts "Returning list of volumes for #{ args['server_name'] } in #{ IDENTITY }..."

  read(args, false, 'name', 'server_name') if @main_obj["specific_#{ IDENTITY }"].nil?

  specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).get @main_obj["specific_#{ IDENTITY }"].last['id']

  @main_obj["#{ IDENTITY }_volume_list_request"] = JSON.parse(specific_fog_object.attachments.all.to_json)

  @main_obj['server_attached_volumes'] ||= {}

  @main_obj['server_attached_volumes'][args['server_name']] ||= []

  @main_obj["#{ IDENTITY }_volume_list_request"].each do |volume_hash|
    @classes['volume'].read volume_hash, false, 'id'

    @main_obj['server_attached_volumes'][args['server_name']] << @main_obj['specific_volumes'].last
  end

  ap( @main_obj['server_attached_volumes'][args['server_name']] ) if output
end

#poll(args) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/cloud_interactor/server/poll.rb', line 3

def poll args
  read args, false

  raise "Server #{ args['name'] } does not exist!" if @main_obj["specific_#{ IDENTITY }"].empty?

  puts "Polling #{ args['name'] } for status...(execution will continue when the server is finished building)"

  specific_fog_object = @classes['auth'].auth_service(RESOURCE).instance_eval(IDENTITY).get @main_obj["specific_#{ IDENTITY }"].last['id']

  #specific_servers is an ARRAY, the latest status of the server is the LAST ENTRY
  duration_hash = specific_fog_object.wait_for { ready? }

  @main_obj['output']["created_servers"] ||= []

  @main_obj['output']["created_servers"] << JSON.parse(specific_fog_object.reload.to_json)

  puts "#{ args['name'] } became active in #{ duration_hash[:duration] } seconds!"
end

#read(args, output = true, mode = "name", search_key = "name") ⇒ Object



3
4
5
6
7
# File 'lib/cloud_interactor/server/read.rb', line 3

def read args, output=true, mode="name", search_key="name"
  list [], false

  @classes['helper'].generic_read_parse args, IDENTITY, output, mode, search_key
end

#read_volume(args, output = true, strict_match = false) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/cloud_interactor/server/read_volume.rb', line 3

def read_volume args, output=true, strict_match=false
  specific_volume = args['volume_name']

  raise "Volume not passed! Value for volume name is: #{ specific_volume }" if specific_volume.nil?

  list_volumes args, false

  @main_obj['server_attached_volumes'][args['server_name']].each do |volume_hash|
    next if strict_match && volume_hash['display_name'] != (specific_volume)
    next if !strict_match && !volume_hash['display_name'].include?(specific_volume)

    @main_obj["specific_attached_volumes"] ||= []
    
    @main_obj["specific_attached_volumes"] << volume_hash

    ap(volume_hash) if output
  end

  puts("#{ specific_volume } not attached to #{ args['server_name'] }!") if @main_obj["specific_attached_volumes"].nil?
end

#run(method, args) ⇒ Object



13
14
15
# File 'lib/cloud_interactor/server.rb', line 13

def run method, args
  self.send(method, args)
end