Class: Inception::InceptionServer

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

Constant Summary collapse

DEFAULT_SERVER_NAME =
"inception"
DEFAULT_FLAVOR =
"m1.small"
DEFAULT_DISK_SIZE =
16
DEFAULT_SECURITY_GROUPS =
["ssh"]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(provider_client, attributes, ssh_dir) ⇒ InceptionServer

Required @attributes:

{
  "name" => "inception",
  "ip_address" => "54.214.15.178",
  "key_pair" => {
    "name" => "inception",
    "private_key" => "private_key",
    "public_key" => "public_key"
  }
}

Including optional @attributes and default values:

{
  "name" => "inception",
  "ip_address" => "54.214.15.178",
  "security_groups" => ["ssh"],
  "flavor" => "m1.small",
  "key_pair" => {
    "name" => "inception",
    "private_key" => "private_key",
    "public_key" => "public_key"
  }
}


39
40
41
42
43
44
# File 'lib/inception/inception_server.rb', line 39

def initialize(provider_client, attributes, ssh_dir)
  @provider_client = provider_client
  @ssh_dir = ssh_dir
  @attributes = attributes.is_a?(Hash) ? ReadWriteSettings.new(attributes) : attributes
  raise "@attributes must be ReadWriteSettings (or Hash)" unless @attributes.is_a?(ReadWriteSettings)
end

Instance Attribute Details

#attributesObject (readonly)

Returns the value of attribute attributes.



11
12
13
# File 'lib/inception/inception_server.rb', line 11

def attributes
  @attributes
end

Instance Method Details

#createObject

Create the underlying server, with key pair & security groups, unless it is already created

The @attributes hash is updated with a ‘provisioned` key during/after creation. When saved as YAML it might look like:

inception:
  provisioned:
    image_id: ami-123456
    server_id: i-e7f005d2
    security_groups:
      - ssh
      - mosh
    username: ubuntu
    disk_device: /dev/sdi
    host: ec2-54-214-15-178.us-west-2.compute.amazonaws.com
    validated: true
    converged: true


62
63
64
65
66
67
68
# File 'lib/inception/inception_server.rb', line 62

def create
  validate_attributes_for_bootstrap
  ensure_required_security_groups
  create_missing_default_security_groups
  bootstrap_vm
  attach_persistent_disk
end

#default_disk_deviceObject



192
193
194
195
196
197
198
199
200
201
# File 'lib/inception/inception_server.rb', line 192

def default_disk_device
  case @provider_client
  when Inception::Providers::Clients::AwsProviderClient
    { "external" => "/dev/sdf", "internal" => "/dev/xvdf" }
  when Inception::Providers::Clients::OpenStackProviderClient
    { "external" => "/dev/vdc", "internal" => "/dev/vdc" }
  else
    raise "Please implement InceptionServer#default_disk_device for #{@provider_client.class}"
  end
end

#delete_allObject

Delete the server, volume and release the IP address



71
72
73
74
75
76
# File 'lib/inception/inception_server.rb', line 71

def delete_all
  delete_server
  delete_volume
  delete_key_pair
  release_ip_address
end

#delete_key_pairObject



106
107
108
109
110
111
112
113
114
115
# File 'lib/inception/inception_server.rb', line 106

def delete_key_pair
  key_pair_name = attributes.exists?("key_pair.name")
  if key_pair_name && key_pair = fog_compute.key_pairs.get(key_pair_name)
    puts "Deleting key pair '#{key_pair_name}'"
    key_pair.destroy
  else
    puts "Keypair already destroyed"
  end
  attributes.delete("key_pair")
end

#delete_serverObject



78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/inception/inception_server.rb', line 78

def delete_server
  @fog_server = nil # force reload of fog_server model
  if fog_server
    print "Deleting server... "
    fog_server.destroy
    wait_for_termination(fog_server) unless Fog.mocking?
    puts "done."
  else
    puts "Server already destroyed"
  end
  provisioned.delete("host")
  provisioned.delete("server_id")
  provisioned.delete("username")
end

#delete_volumeObject



93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/inception/inception_server.rb', line 93

def delete_volume
  volume_id = provisioned.exists?("disk_device.volume_id")
  if volume_id && (volume = fog_compute.volumes.get(volume_id)) && volume.ready?
    print "Deleting volume... "
    volume.destroy
    wait_for_termination(volume, "deleting")
    puts ""
  else
    puts "Volume already destroyed"
  end
  provisioned.delete("disk_device")
end

#disk_devicesObject



184
185
186
# File 'lib/inception/inception_server.rb', line 184

def disk_devices
  provisioned["disk_device"] ||= default_disk_device
end

#disk_sizeObject

Size of attached persistent disk for the inception server



157
158
159
# File 'lib/inception/inception_server.rb', line 157

def disk_size
  @attributes["disk_size"] ||= DEFAULT_DISK_SIZE
end

#export_attributesObject

Because @attributes is not the same as @attributes.provisioned we need a helper to export the complete nested attributes.



178
179
180
181
182
# File 'lib/inception/inception_server.rb', line 178

def export_attributes
  attrs = attributes.to_nested_hash
  attrs["provisioned"] = provisioned.to_nested_hash
  attrs
end

#external_disk_deviceObject



188
189
190
# File 'lib/inception/inception_server.rb', line 188

def external_disk_device
  disk_devices["external"]
end

#flavorObject

Flavor/instance type of the server to be provisioned TODO: DEFAULT_FLAVOR should become IaaS/provider specific



152
153
154
# File 'lib/inception/inception_server.rb', line 152

def flavor
  @attributes["flavor"] ||= DEFAULT_FLAVOR
end

#fog_computeObject



215
216
217
# File 'lib/inception/inception_server.rb', line 215

def fog_compute
  @provider_client.fog_compute
end

#fog_serverObject



207
208
209
210
211
212
213
# File 'lib/inception/inception_server.rb', line 207

def fog_server
  @fog_server ||= begin
    if server_id = provisioned["server_id"]
      fog_compute.servers.get(server_id)
    end
  end
end

#image_idObject



165
166
167
# File 'lib/inception/inception_server.rb', line 165

def image_id
  @attributes["image_id"] ||= @provider_client.image_id
end

#ip_addressObject



161
162
163
# File 'lib/inception/inception_server.rb', line 161

def ip_address
  provisioned.ip_address
end

#key_nameObject



138
139
140
# File 'lib/inception/inception_server.rb', line 138

def key_name
  @attributes.key_pair.name
end

#private_key_pathObject



142
143
144
# File 'lib/inception/inception_server.rb', line 142

def private_key_path
  @private_key_path ||= File.join(@ssh_dir, key_name)
end

#provisionedObject

The progresive/final attributes of the provisioned Inception server & persistent disk.



171
172
173
174
# File 'lib/inception/inception_server.rb', line 171

def provisioned
  @attributes["provisioned"] = {} unless @attributes["provisioned"]
  @attributes.provisioned
end

#public_keyObject



146
147
148
# File 'lib/inception/inception_server.rb', line 146

def public_key
  @attributes.exists?("key_pair.public_key")
end

#release_ip_addressObject



118
119
120
121
122
123
124
125
126
127
# File 'lib/inception/inception_server.rb', line 118

def release_ip_address
  public_ip = provisioned.exists?("ip_address")
  if public_ip && ip_address = fog_compute.addresses.get(public_ip)
    puts "Releasing IP address #{public_ip}"
    ip_address.destroy
  else
    puts "IP address already released"
  end
  provisioned.delete("ip_address")
end

#security_groupsObject



129
130
131
# File 'lib/inception/inception_server.rb', line 129

def security_groups
  @attributes.security_groups
end

#server_nameObject



133
134
135
136
# File 'lib/inception/inception_server.rb', line 133

def server_name
  @attributes["name"] ||= DEFAULT_SERVER_NAME
  @attributes.name
end

#user_hostObject



203
204
205
# File 'lib/inception/inception_server.rb', line 203

def user_host
  "#{provisioned.username}@#{provisioned.host}"
end