Class: ZAWS::EC2Services::Compute

Inherits:
Object
  • Object
show all
Defined in:
lib/zaws/ec2/compute.rb

Instance Method Summary collapse

Constructor Details

#initialize(shellout, aws) ⇒ Compute

Returns a new instance of Compute.



9
10
11
12
# File 'lib/zaws/ec2/compute.rb', line 9

def initialize(shellout,aws)
		@shellout=shellout
		@aws=aws
end

Instance Method Details

#add_volume(region, instanceid, externalid, ip, volume, zone, volsize, verbose = nil) ⇒ Object



191
192
193
194
195
196
197
198
199
200
# File 'lib/zaws/ec2/compute.rb', line 191

def add_volume(region,instanceid,externalid,ip,volume,zone,volsize,verbose=nil)
		comline = "aws --output json --region #{region} ec2 create-volume --availability-zone #{zone} --size #{volsize}"
		new_volume=JSON.parse(@shellout.cli(comline,verbose))
		new_volumeid=new_volume["VolumeId"]
		tag_resource(region,new_volumeid,externalid,verbose)
		if instance_ping?(ip,10,1)
 comline = "aws --output json ec2 attach-volume --region #{region} --volume-id #{new_volumeid} --instance-id #{instanceid} --device #{volume}"
 volattach=JSON.parse(@shellout.cli(comline,verbose))
		end
end

#assoc_security_group(region, textout, verbose, vpcid, externalid, sgroup) ⇒ Object



137
138
139
140
141
142
143
144
145
146
147
# File 'lib/zaws/ec2/compute.rb', line 137

def assoc_security_group(region,textout,verbose,vpcid,externalid,sgroup)
		assoc_exists,instance_id,sgroupid=exists_security_group_assoc(region,nil,verbose,vpcid,externalid,sgroup)
		if not assoc_exists 
 comline = "aws --region #{region} ec2 modify-instance-attribute --instance-id #{instance_id} --groups #{sgroupid}"
 verbose.puts "comline=#{comline}" if verbose
 assocsgroup=JSON.parse(@shellout.cli(comline,verbose))
 textout.puts "Security Group Association Changed." if assocsgroup["return"]=="true"
		else
 textout.puts "Security Group Association Not Changed." 	
		end
end

#block_device_mapping(region, owner, verbose, rootsize, imageid) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/zaws/ec2/compute.rb', line 58

def block_device_mapping(region,owner,verbose,rootsize,imageid)
		image_descriptions=JSON.parse(view_images(region,'json',owner,imageid,nil,verbose))
		image_mappings=image_descriptions['Images'][0]["BlockDeviceMappings"]
		image_root=image_descriptions['Images'][0]["RootDeviceName"]
		image_mappings.each do |x|
 if x["DeviceName"]==image_root
if x["Ebs"]["VolumeSize"].to_i > rootsize.to_i
  raiseerror "The image root size is greater than the specified root size. image=#{x["Ebs"]["VolumeSize"]} > rootsize=#{rootsize}"
  exit 1
end
x["Ebs"]["VolumeSize"]=rootsize.to_i
         x["Ebs"].delete("Encrypted") if x["Ebs"]["SnapshotId"] #You cannot specify the encrypted flag if specifying a snapshot id in a block device mapping. -AWS
 end
		end
		return image_mappings.to_json
end

#declare(externalid, image, owner, nodetype, root, zone, key, sgroup, privateip, optimized, apiterminate, clienttoken, region, textout, verbose, vpcid, nagios, ufile, no_sdcheck, skip_running_check, volsize, volume) ⇒ Object



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
# File 'lib/zaws/ec2/compute.rb', line 79

def declare(externalid,image,owner,nodetype,root,zone,key,sgroup,privateip,optimized,apiterminate,clienttoken,region,textout,verbose,vpcid,nagios,ufile,no_sdcheck,skip_running_check,volsize,volume)
		if ufile
 ZAWS::Helper::ZFile.prepend("zaws compute delete #{externalid} --region #{region} --vpcid #{vpcid} $XTRA_OPTS",'#Delete instance',ufile)
		end
		compute_exists,instance_id,sgroups = exists(region,nil,verbose,vpcid,externalid)
		return ZAWS::Helper::Output.binary_nagios_check(compute_exists,"OK: Instance already exists.","CRITICAL: Instance does not exist.",textout) if nagios
		if not compute_exists
 clienttoken=random_clienttoken if not clienttoken
 comline = "aws --region #{region} ec2 run-instances --image-id #{image} --key-name #{key} --instance-type #{nodetype}"
 #comline = comline + " --user-data 'file://#{options[:userdata]}'" if options[:userdata]
 comline = comline + " --placement AvailabilityZone=#{zone}" if zone
 comline = comline + " --block-device-mappings '#{block_device_mapping(region,owner,verbose,root,image)}'" if root
 comline = apiterminate ? comline + " --enable-api-termination" : comline + " --disable-api-termination"
 comline = comline + " --client-token #{clienttoken}"
 comline = comline + " --network-interfaces '#{network_interface_json(region,verbose,vpcid,privateip[0],sgroup)}'" if privateip # Difference between vpc and classic
 #comline = comline + " --security-groups '#{options[:securitygroup]}'" if not options[:privateip]
 #comline = comline + " --iam-instance-profile Name='#{options[:profilename]}'" if options[:profilename]
 comline = optimized ? comline + " --ebs-optimized" : comline + " --no-ebs-optimized"
 newinstance=JSON.parse(@shellout.cli(comline,verbose))
 textout.puts "Instance created." if (newinstance["Instances"] and newinstance["Instances"][0]["InstanceId"])
 new_instanceid=newinstance["Instances"][0]["InstanceId"]
 tag_resource(region,new_instanceid,externalid,verbose)
 instance_running?(region,vpcid,externalid,60,5,verbose) if not skip_running_check
 add_volume(region,new_instanceid,externalid,privateip,volume,zone,volsize,verbose) if volume
 nosdcheck(region,new_instanceid,verbose) if no_sdcheck # Needed for NAT instances.
		else
 textout.puts "Instance already exists. Creation skipped."
		end

end

#declare_secondary_ip(region, ip, textout, verbose, vpcid, externalid, nagios, ufile) ⇒ Object



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/zaws/ec2/compute.rb', line 215

def declare_secondary_ip(region,ip,textout,verbose,vpcid,externalid,nagios,ufile)
		if ufile
 ZAWS::Helper::ZFile.prepend("zaws compute delete_secondary_ip #{externalid} #{ip} --region #{region} --vpcid #{vpcid} $XTRA_OPTS",'#Delete secondary ip',ufile)
		end
		compute_exists,instance_id,sgroups = exists(region,nil,verbose,vpcid,externalid)
		secondary_ip_exists,compute_exists,network_interface = exists_secondary_ip(region,ip,nil,verbose,vpcid,externalid)
		return ZAWS::Helper::Output.binary_nagios_check(secondary_ip_exists,"OK: Secondary ip exists.","CRITICAL: Secondary ip does not exist.",textout) if nagios
		if not secondary_ip_exists and compute_exists
 comline = "aws --output json --region #{region} ec2 assign-private-ip-addresses --network-interface-id '#{network_interface}' --private-ip-addresses '#{ip}'"
 $stdout.puts comline
 assignreturn = JSON.parse(@shellout.cli(comline,verbose))
 textout.puts "Secondary ip assigned." if assignreturn["return"] == "true"
		else
 textout.puts "Secondary ip already exists. Skipping assignment." 
		end
end

#delete(region, textout = nil, verbose = nil, vpcid, externalid) ⇒ Object



110
111
112
113
114
115
116
117
118
119
# File 'lib/zaws/ec2/compute.rb', line 110

def delete(region,textout=nil,verbose=nil,vpcid,externalid)
		compute_exists,instance_id,sgroups = exists(region,nil,verbose,vpcid,externalid)
		if compute_exists
 comline = "aws --region #{region} ec2 terminate-instances --instance-ids #{instance_id}"
 delinstance=JSON.parse(@shellout.cli(comline,verbose))
 textout.puts "Instance deleted." if delinstance["TerimatingInstances"]
		else
 textout.puts "Instance does not exist. Skipping deletion." 
		end
end

#delete_secondary_ip(region, ip, textout, verbose, vpcid, externalid) ⇒ Object



232
233
234
235
236
237
238
239
240
241
# File 'lib/zaws/ec2/compute.rb', line 232

def delete_secondary_ip(region,ip,textout,verbose,vpcid,externalid)
		secondary_ip_exists,compute_exists,network_interface = exists_secondary_ip(region,ip,nil,verbose,vpcid,externalid)
		if secondary_ip_exists and compute_exists
 comline = "aws --output json --region #{region} ec2 unassign-private-ip-addresses --network-interface-id '#{network_interface}' --private-ip-addresses '#{ip}'"
 assignreturn = JSON.parse(@shellout.cli(comline,verbose))
 textout.puts "Secondary ip deleted." if assignreturn["return"] == "true"
		else
 textout.puts "Secondary IP does not exists, skipping deletion." 
		end
end

#exists(region, textout = nil, verbose = nil, vpcid, externalid) ⇒ Object



35
36
37
38
39
40
41
42
# File 'lib/zaws/ec2/compute.rb', line 35

def exists(region,textout=nil,verbose=nil,vpcid,externalid)
		instances=JSON.parse(view(region,'json',nil,verbose,vpcid,externalid))
		val = (instances["Reservations"].count == 1) && (instances["Reservations"][0]["Instances"].count == 1)
		instance_id = val ? instances["Reservations"][0]["Instances"][0]["InstanceId"] : nil
		sgroups = val ? instances["Reservations"][0]["Instances"][0]["SecurityGroups"] : nil
		textout.puts val.to_s if textout
		return val, instance_id, sgroups
end

#exists_secondary_ip(region, ip, textout, verbose, vpcid, externalid) ⇒ Object



202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/zaws/ec2/compute.rb', line 202

def exists_secondary_ip(region,ip,textout,verbose,vpcid,externalid)
		compute_exists,instance_id,sgroups = exists(region,nil,verbose,vpcid,externalid)
		if compute_exists
 query_instance=JSON.parse(view(region,'json',nil,verbose,vpcid,externalid))
 val = query_instance["Reservations"][0]["Instances"][0]["NetworkInterfaces"][0]["PrivateIpAddresses"].any? { |x| x["PrivateIpAddress"] == "#{ip}" }
 netid = query_instance["Reservations"][0]["Instances"][0]["NetworkInterfaces"][0]["NetworkInterfaceId"]
 textout.puts val if textout
 return val,true,netid
		else
 return false,false,nil
		end
end

#exists_security_group_assoc(region, textout, verbose, vpcid, externalid, sgroup) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/zaws/ec2/compute.rb', line 121

def exists_security_group_assoc(region,textout,verbose,vpcid,externalid,sgroup)
		compute_exists,instance_id,sgroups = exists(region,nil,verbose,vpcid,externalid)
		sgroup_exists,sgroupid = @aws.ec2.security_group.exists(region,nil,verbose,vpcid,sgroup) 
		verbose.puts "compute_exists=#{compute_exists}" if verbose
		verbose.puts "sgroup_exists=#{sgroup_exists}" if verbose
		verbose.puts "sgroups=#{sgroups}" if verbose
		if compute_exists and sgroup_exists
 assoc_exists = sgroups.any? { |z|  z["GroupId"] == "#{sgroupid}" }
 textout.puts assoc_exists if textout
 return assoc_exists, instance_id, sgroupid
		else
 textout.puts false if textout
 return false, instance_id, sgroupid
		end
end

#instance_id_by_external_id(region, externalid, vpcid = nil, textout = nil, verbose = nil) ⇒ Object



44
45
46
47
# File 'lib/zaws/ec2/compute.rb', line 44

def instance_id_by_external_id(region,externalid,vpcid=nil,textout=nil,verbose=nil) 
		val,instance_id,sgroups=exists(region,nil,verbose,vpcid,externalid)
		return instance_id
end

#instance_ping?(ip, statetimeout, sleeptime, verbose = nil) ⇒ Boolean

Returns:

  • (Boolean)


161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/zaws/ec2/compute.rb', line 161

def instance_ping?(ip,statetimeout,sleeptime,verbose=nil)
		begin
 Timeout.timeout(statetimeout) do
begin
  comline ="ping -q -c 2 #{ip}"
  @shellout.cli(comline,verbose)
rescue Mixlib::ShellOut::ShellCommandFailed
  sleep(sleeptime)
  retry
end  
 end
		rescue Timeout::Error
 raise StandardError.new('Timeout before instance responded to ping.')
		end
		return true
end

#instance_running?(region, vpcid, externalid, statetimeout, sleeptime, verbose = nil) ⇒ Boolean

Returns:

  • (Boolean)


178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/zaws/ec2/compute.rb', line 178

def instance_running?(region,vpcid,externalid,statetimeout,sleeptime,verbose=nil)
		begin
 Timeout.timeout(statetimeout) do
begin
  sleep(sleeptime)
  query_instance=JSON.parse(view(region,'json',nil,verbose,vpcid,externalid))
end while query_instance["Reservations"][0]["Instances"][0]["State"]["Code"]!=16
 end
		rescue Timeout::Error
 raise StandardError.new('Timeout before instance state code set to running(16).')
		end
end

#network_interface_json(region, verbose, vpcid, ip, groupname) ⇒ Object



49
50
51
52
53
54
55
56
# File 'lib/zaws/ec2/compute.rb', line 49

def network_interface_json(region,verbose,vpcid,ip,groupname)
		ec2_dir = File.dirname(__FILE__)
		ip_to_subnet_id = @aws.ec2.subnet.id_by_ip(region,nil,verbose,vpcid,ip)
		subnet_id=ip_to_subnet_id
		security_group_id= @aws.ec2.security_group.id_by_name(region,nil,verbose,vpcid,groupname)
		new_hash= [{ "Groups"=> [security_group_id], "PrivateIpAddress"=>"#{ip}","DeviceIndex"=>0,"SubnetId"=> ip_to_subnet_id }]
		return new_hash.to_json
end

#nosdcheck(region, instanceid, verbose = nil) ⇒ Object



156
157
158
159
# File 'lib/zaws/ec2/compute.rb', line 156

def nosdcheck(region,instanceid,verbose=nil)
		comline = "aws --output json --region #{region} ec2 modify-instance-attribute --instance-id=#{instanceid} --no-source-dest-check"
		nosdcheck_result=JSON.parse(@shellout.cli(comline,verbose))
end

#random_clienttokenObject



75
76
77
# File 'lib/zaws/ec2/compute.rb', line 75

def random_clienttoken
		(0...8).map { (65 + rand(26)).chr }.join
end

#tag_resource(region, resourceid, externalid, verbose = nil) ⇒ Object



149
150
151
152
153
154
# File 'lib/zaws/ec2/compute.rb', line 149

def tag_resource(region,resourceid,externalid,verbose=nil)
		comline="aws --output json --region #{region} ec2 create-tags --resources #{resourceid} --tags Key=externalid,Value=#{externalid}"
		tag_creation=JSON.parse(@shellout.cli(comline,verbose))
		comline="aws --output json --region #{region} ec2 create-tags --resources #{resourceid} --tags Key=Name,Value=#{externalid}"
		tag_creation=JSON.parse(@shellout.cli(comline,verbose))
end

#view(region, viewtype, textout = nil, verbose = nil, vpcid = nil, externalid = nil) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/zaws/ec2/compute.rb', line 14

def view(region,viewtype,textout=nil,verbose=nil,vpcid=nil,externalid=nil)
		comline="aws --output #{viewtype} --region #{region} ec2 describe-instances"
		if vpcid || externalid 
 comline = comline + " --filter"
		end
		comline = comline + " 'Name=vpc-id,Values=#{vpcid}'" if vpcid 
		comline = comline + " 'Name=tag:externalid,Values=#{externalid}'" if externalid 
		instances=@shellout.cli(comline,verbose)
		textout.puts(instances) if textout
		return instances
end

#view_images(region, viewtype, owner, imageid, textout = nil, verbose = nil) ⇒ Object



26
27
28
29
30
31
32
33
# File 'lib/zaws/ec2/compute.rb', line 26

def view_images(region,viewtype,owner,imageid,textout=nil,verbose=nil)
		comline="aws --output #{viewtype} --region #{region} ec2 describe-images"
		comline = "#{comline} --owner #{owner}" if owner 
		comline = "#{comline} --image-ids #{imageid}" if imageid 
		images=@shellout.cli(comline,verbose)
		textout.puts(images) if textout
		return images
end