An array of hashes with dorky-looking keys, just like Fog wants it.
# File lib/ironfan/provider/ec2/machine.rb, line 263 def self.block_device_mapping(computer) Ironfan.todo "CODE SMELL: Machine is too familiar with EbsVolume problems" computer.drives.values.map do |drive| next if drive.disk # Don't create any disc already satisfied volume = drive.volume or next hsh = { 'DeviceName' => volume.device } if volume.attachable == 'ephemeral' hsh['VirtualName'] = drive.name # if set for creation at launch (and not already created) elsif drive.node[:volume_id].blank? && volume.create_at_launch if volume.snapshot_id.blank? && volume.size.blank? raise "Must specify a size or a snapshot ID for #{volume}" end hsh['Ebs.SnapshotId'] = volume.snapshot_id if volume.snapshot_id.present? hsh['Ebs.VolumeSize'] = volume.size.to_s if volume.size.present? hsh['Ebs.DeleteOnTermination'] = (not volume.keep).to_s else next end hsh end.compact end
Manipulation
# File lib/ironfan/provider/ec2/machine.rb, line 147 def self.create!(computer) Ironfan.todo("CODE SMELL: overly large method: #{caller}") return if computer.machine? and computer.machine.created? Ironfan.step(computer.name,"creating cloud machine", :green) # errors = lint(computer) if errors.present? then raise ArgumentError, "Failed validation: #{errors.inspect}" ; end # launch_desc = launch_description(computer) Chef::Log.debug(JSON.pretty_generate(launch_desc)) Ironfan.safely do fog_server = Ec2.connection.servers.create(launch_desc) machine = Machine.new(:adaptee => fog_server) computer.machine = machine remember machine, :id => computer.name fog_server.wait_for { ready? } end # tag the computer correctly tags = { 'cluster' => computer.server.cluster_name, 'facet' => computer.server.facet_name, 'index' => computer.server.index, 'name' => computer.name, 'Name' => computer.name, } Ec2.ensure_tags(tags, computer.machine) # register the new volumes for later save!, and tag appropriately computer.machine.volumes.each do |v| Ironfan.todo "CODE SMELL: Machine is too familiar with EbsVolume problems" ebs_vol = Ec2::EbsVolume.register v drive = computer.drives.values.select do |drive| drive.volume.device == ebs_vol.device end.first drive.disk = ebs_vol vol_name = "#{computer.name}-#{drive.volume.name}" tags['server'] = computer.name tags['name'] = vol_name tags['Name'] = vol_name tags['mount_point'] = drive.volume.mount_point tags['device'] = drive.volume.device Ec2.ensure_tags(tags,ebs_vol) end end
# File lib/ironfan/provider/ec2/machine.rb, line 285 def self.destroy!(computer) return unless computer.machine? forget computer.machine.name computer.machine.destroy computer.machine.reload # show the node as shutting down end
# File lib/ironfan/provider/ec2/machine.rb, line 41 def self.expected_ids(computer) [computer.server.full_name]; end
# File lib/ironfan/provider/ec2/machine.rb, line 213 def self.launch_description(computer) cloud = computer.server.cloud(:ec2) user_data_hsh = { :chef_server => Chef::Config[:chef_server_url], # :validation_client_name => Chef::Config[:validation_client_name], # :node_name => computer.name, :organization => Chef::Config[:organization], :cluster_name => computer.server.cluster_name, :facet_name => computer.server.facet_name, :facet_index => computer.server.index, :client_key => computer.private_key } # Fog does not actually create tags when it creates a server; # they and permanence are applied during sync description = { :image_id => cloud.image_id, :flavor_id => cloud.flavor, :vpc_id => cloud.vpc, :subnet_id => cloud.subnet, :key_name => cloud.ssh_key_name(computer), :user_data => JSON.pretty_generate(user_data_hsh), :block_device_mapping => block_device_mapping(computer), :availability_zone => cloud.default_availability_zone, :monitoring => cloud.monitoring } # VPC security_groups can only be addressed by id (not name) description[:security_group_ids] = cloud.security_groups.keys.map do |g| group_name = cloud.vpc.nil? ? g.to_s : "#{cloud.vpc}:#{g}" SecurityGroup.recall(group_name).group_id end description[:iam_server_certificates] = cloud.iam_server_certificates.values.map do |cert| IamServerCertificate.recall(IamServerCertificate.full_name(computer, cert)) end.compact.map(&:name) description[:elastic_load_balancers] = cloud.elastic_load_balancers.values.map do |elb| ElasticLoadBalancer.recall(ElasticLoadBalancer.full_name(computer, elb)) end.compact.map(&:name) if cloud.flavor_info[:placement_groupable] ui.warn "1.3.1 and earlier versions of Fog don't correctly support placement groups, so your nodes will land willy-nilly. We're working on a fix" description[:placement] = { 'groupName' => cloud.placement_group.to_s } end description end
@returns [Hash{String, Array}] of ‘what you did wrong’ => [relevant, info]
# File lib/ironfan/provider/ec2/machine.rb, line 197 def self.lint(computer) cloud = computer.server.cloud(:ec2) info = [computer.name, cloud.inspect] errors = {} server_errors = computer.server.lint errors["Unhappy Server"] = server_errors if server_errors.present? errors["No AMI found"] = info if cloud.image_id.blank? errors['Missing client'] = info unless computer.client? errors['Missing private_key'] = computer.client unless computer.private_key # all_asserted_regions = [Ec2.connection.region, cloud.region, Chef::Config[:knife][:region], Ironfan.chef_config[:region]].compact.uniq errors["mismatched region"] = all_asserted_regions unless all_asserted_regions.count == 1 # errors end
Discovery
# File lib/ironfan/provider/ec2/machine.rb, line 104 def self.load!(cluster=nil) Ec2.connection.servers.each do |fs| machine = new(:adaptee => fs) if (not machine.created?) next unless Ironfan.chef_config[:include_terminated] remember machine, :append_id => "terminated:#{machine.id}" elsif recall? machine.name machine.bogus << :duplicate_machines recall(machine.name).bogus << :duplicate_machines remember machine, :append_id => "duplicate:#{machine.id}" else # never seen it remember machine end Chef::Log.debug("Loaded #{machine}") end end
# File lib/ironfan/provider/ec2/machine.rb, line 38 def self.multiple?() false; end
def self.resource_type() Ironfan::IaasProvider::Machine; end
# File lib/ironfan/provider/ec2/machine.rb, line 40 def self.resource_type() :machine; end
# File lib/ironfan/provider/ec2/machine.rb, line 292 def self.save!(computer) return unless computer.machine? # the EC2 API does not surface disable_api_termination as a value, so we # have to set it every time. permanent = computer.server.cloud(:ec2).permanent return unless computer.created? Ironfan.step(computer.name, "setting termination flag #{permanent}", :blue) Ironfan.unless_dry_run do Ironfan.safely do Ec2.connection.modify_instance_attribute( computer.machine.id, {'DisableApiTermination.Value' => computer.permanent?, }) end end end
Find active machines that haven’t matched, but should have,
make sure all bogus machines have a computer to attach to for display purposes
# File lib/ironfan/provider/ec2/machine.rb, line 129 def self.validate_resources!(computers) recall.each_value do |machine| next unless machine.users.empty? and machine.name if machine.name.match("^#{computers.cluster.name}-") machine.bogus << :unexpected_machine end next unless machine.bogus? fake = Ironfan::Broker::Computer.new fake[:machine] = machine fake.name = machine.name machine.users << fake computers << fake end end
# File lib/ironfan/provider/ec2/machine.rb, line 51 def created? not ['terminated', 'shutting-down'].include? state end
# File lib/ironfan/provider/ec2/machine.rb, line 49 def keypair ; key_pair ; end
# File lib/ironfan/provider/ec2/machine.rb, line 43 def name return id if tags.empty? tags["Name"] || tags["name"] || id end
# File lib/ironfan/provider/ec2/machine.rb, line 48 def public_hostname ; dns_name ; end
# File lib/ironfan/provider/ec2/machine.rb, line 121 def receive_adaptee(obj) obj = Ec2.connection.servers.new(obj) if obj.is_a?(Hash) super end
# File lib/ironfan/provider/ec2/machine.rb, line 54 def running? state == "running" end
# File lib/ironfan/provider/ec2/machine.rb, line 92 def ssh_key keypair = cloud.keypair || computer.server.cluster_name end
# File lib/ironfan/provider/ec2/machine.rb, line 61 def start adaptee.start adaptee.wait_for{ state == 'pending' } end
# File lib/ironfan/provider/ec2/machine.rb, line 66 def stop adaptee.stop adaptee.wait_for{ state == 'stopping' } end
# File lib/ironfan/provider/ec2/machine.rb, line 57 def stopped? state == "stopped" end
# File lib/ironfan/provider/ec2/machine.rb, line 71 def to_display(style,values={}) # style == :minimal values["State"] = state.to_sym values["MachineID"] = id values["Public IP"] = public_ip_address values["Private IP"] = private_ip_address values["Created On"] = created_at.to_date return values if style == :minimal # style == :default values["Flavor"] = flavor_id values["AZ"] = availability_zone return values if style == :default # style == :expanded values["Image"] = image_id values["Volumes"] = volumes.map(&:id).join(', ') values["SSH Key"] = key_name values end
# File lib/ironfan/provider/ec2/machine.rb, line 96 def to_s "<%-15s %-12s %-25s %-25s %-15s %-15s %-12s %-12s %s:%s>" % [ self.class.handle, id, created_at, tags['name'], private_ip_address, public_ip_address, flavor_id, availability_zone, key_name, groups.join(',') ] end
Generated with the Darkfish Rdoc Generator 2.