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
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
# File 'lib/avst-cloud/aws_connection.rb', line 36
def create_server(server_name, flavour, os, key_name, ssh_key, subnet_id, security_group_ids, ebs_size, hdd_device_path, ami_image_id, availability_zone, additional_hdds={}, vpc=nil, created_by=nil, custom_tags={}, root_username=nil, create_elastic_ip=false, encrypt_root=false ,root_encryption_key=nil, delete_root_disk=true, root_disk_type='gp2', root_disk_iops=0, private_ip=nil, public_ip=nil)
flavour = flavour || "t2.micro"
os = os || "ubuntu-14"
ami_image_id = ami_image_id || "ami-f0b11187"
device_name = hdd_device_path || '/dev/sda1'
root_user = root_username || user_from_os(os)
unless File.file?(ssh_key)
logger.error "Could not find local SSH key '#{ssh_key}'".red
raise "Could not find local SSH key '#{ssh_key}'"
end
existing_servers = all_named_servers(server_name)
restartable_servers = existing_servers.select{ |serv| serv.state == 'stopped' }
running_servers = existing_servers.select{ |serv| serv.state != 'stopped' && serv.state != 'terminated' }
if running_servers.length > 0
running_servers.each do |server|
logger.error "Server #{server_name} with id #{server.id} found in state: #{server.state}".yellow
end
raise "Server with the same name found!"
elsif restartable_servers.length > 0
if restartable_servers.length > 1
running_servers.each do |server|
logger.error "Server #{server_name} with id #{server.id} found in state: #{server.state}. Can not restart".yellow
end
raise "Too many servers can be restarted."
end
server = restartable_servers.first
server.start
result_server = AvstCloud::AwsServer.new(server, server_name, server.public_ip_address, root_user, ssh_key)
result_server.wait_for_state() {|serv| serv.ready?}
logger.debug "[DONE]\n\n"
logger.debug "The server was successfully re-started.\n\n"
result_server
else
logger.debug "Creating EC2 server:"
logger.debug "Server name - #{server_name}"
logger.debug "Operating system - #{os}"
logger.debug "image_template_id - #{ami_image_id}"
logger.debug "flavour - #{flavour}"
logger.debug "key_name - #{key_name}"
logger.debug "ssh_key - #{ssh_key}"
logger.debug "root user - #{root_user}"
logger.debug "subnet_id - #{subnet_id}"
logger.debug "security_group_ids - #{security_group_ids}"
logger.debug "region - #{@region}"
logger.debug "availability_zone - #{availability_zone}"
logger.debug "ebs_size - #{ebs_size}"
logger.debug "hdd_device_path - #{device_name}"
logger.debug "additional_hdds - #{additional_hdds}"
logger.debug "vpc - #{vpc}"
logger.debug "create_elastic_ip - #{create_elastic_ip}"
logger.debug "custom_private_ip - #{private_ip}"
elastic_ip_address = nil
if public_ip
require "resolv"
if public_ip =~ Resolv::IPv4::Regex
found_eip = connect.describe_addresses('public-ip' => [public_ip])
else
found_eip = connect.describe_addresses('tag:Name' => [public_ip])
end
if ! found_eip.data[:body]['addressesSet'][0].nil?
if found_eip.data[:body]['addressesSet'][0]['publicIp'] and ! found_eip.data[:body]['addressesSet'][0]['associationId']
elastic_ip =found_eip.data[:body]['addressesSet'][0]
elastic_ip_address = elastic_ip['publicIp']
logger.debug "Requested Elastic IP found and is unallocated, an attempt to attach this to the VM will be made"
else
logger.warn "Requested Elastic IP exist but is already allocated, the system will be created but will NOT use this IP"
end
else
logger.warn "Requested Elastic IP does not exist, the system will be created but will NOT use this IP"
end
end
create_ebs_volume = nil
if ebs_size
root_disk = {
:DeviceName => device_name,
'Ebs.VolumeType' => root_disk_type,
'Ebs.VolumeSize' => ebs_size,
}
if encrypt_root
root_disk.merge!('Ebs.Encrypted' => true, 'Ebs.KmsKeyId' => root_encryption_key||nil )
end
if delete_root_disk == false || delete_root_disk == 'false'
root_disk.merge!('Ebs.DeleteOnTermination' => false)
end
if root_disk_type == 'io1'
root_disk.merge!('Ebs.Iops' => root_disk_iops)
end
create_ebs_volume = [ root_disk ]
if additional_hdds and additional_hdds.is_a?(Hash)
additional_hdds.each_value do |disk|
volume_type = disk['volume_type'] || 'gp2'
if disk['device_name'] && disk['ebs_size']
disk_hash = {
:DeviceName => disk['device_name'],
'Ebs.VolumeType' => volume_type,
'Ebs.VolumeSize' => disk['ebs_size']
}
if disk['encrypted']
disk_hash.merge!('Ebs.Encrypted' => true, 'Ebs.KmsKeyId' => disk['encryption_key_id'] || nil)
end
if disk['delete_disk_with_vm'] == false || disk['delete_disk_with_vm'] == 'false'
disk_hash.merge!('Ebs.DeleteOnTermination' => false)
end
if volume_type == 'io1'
disk_hash.merge!('Ebs.Iops' => disk['volume_iops'] || 0)
end
create_ebs_volume << disk_hash
else
logger.warn "Failed to create additional hdd, required params device_name (e.g. /dev/sda1) or ebs_size missing: #{disk}"
end
end
end
end
tags = {
'Name' => server_name,
'os' => os
}
if created_by
tags['created_by'] = created_by
end
tags.merge!(custom_tags)
server = connect.servers.create :tags => tags,
:flavor_id => flavour,
:image_id => ami_image_id,
:key_name => key_name,
:subnet_id => subnet_id,
:associate_public_ip => true,
:security_group_ids => security_group_ids,
:availability_zone => availability_zone,
:block_device_mapping => create_ebs_volume,
:vpc => vpc,
:private_ip_address => private_ip
result_server = AvstCloud::AwsServer.new(server, server_name, nil, root_user, ssh_key)
result_server.wait_for_state() {|serv| serv.ready?}
logger.debug "[DONE]\n\n"
if create_elastic_ip
if elastic_ip_address.nil?
logger.debug("Attempting to create elastic IP address")
elastic_ip = connect.allocate_address("vpc").body
elastic_ip_address = elastic_ip['publicIp']
logger.warn "Elastic IP creation failed, proceeding with non Elastic IP\n\n" if ! elastic_ip_address
else
logger.warn "You have asked to create an Elastic IP and ALSO use an existing one"
logger.warn "The existing IP is avaliable and as such will be used INSTEAD of creating a new one!"
end
end
if server.id and elastic_ip_address
logger.debug ("Attempting to allocate Elastic IP #{elastic_ip_address} to server")
connect.associate_address(server.id, elastic_ip_address)
server = find_fog_server(server_name)
logger.debug("Creating tags on Elastic IP Address #{elastic_ip}\n\n")
connect.tags.create(:resource_id => elastic_ip['allocationId'], :key => "Name", :value => server_name)
else
logger.warn("EAllocation of Elastic IP failed, proceeding with non Elastic IP\n\n")
end
logger.debug "The server has been successfully created, to login onto the server:\n"
logger.debug "\t ssh -i #{ssh_key} #{root_user}@#{server.public_ip_address}\n"
if create_ebs_volume
logger.debug("Creating tags on ebs volumes")
ebs_volumes = server.block_device_mapping
logger.debug("Creating tags on ebs volumes #{ebs_volumes}")
ebs_volumes.each do |ebs_volume|
if ebs_volume['volumeId']
tags.each do |key, value|
connect.tags.create(:resource_id => ebs_volume['volumeId'], :key => key, :value => value)
end
end
end
end
result_server.ip_address = server.public_ip_address
result_server
end
end
|