lib/dcmgr/endpoints/metadata.rb in wakame-vdc-dcmgr-10.12.0 vs lib/dcmgr/endpoints/metadata.rb in wakame-vdc-dcmgr-11.06.0
- old
+ new
@@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
require 'extlib'
require 'sinatra/base'
+require 'sinatra/sequel_transaction'
require 'yaml'
require 'json'
require 'dcmgr'
@@ -19,33 +20,29 @@
# over all information that the VM needs for self recoginition.
module Dcmgr
module Endpoints
class Metadata < Sinatra::Base
include Dcmgr::Logger
+ register Sinatra::SequelTransaction
disable :sessions
disable :show_exceptions
- LATEST_PROVIDER_VER_ID='2010-11-01'
+ LATEST_PROVIDER_VER_ID='2011-05-19'
get '/' do
''
end
+ get '/:version/meta-data/:data' do
+ get_data(params)
+ end
+
get '/:version/metadata.*' do
#get %r!\A/(\d{4}-\d{2}-\d{2})/metadata.(\w+)\Z! do
- v = params[:version]
+ v = parse_version params[:version]
ext = params[:splat][0]
- v = case v
- when 'latest'
- LATEST_PROVIDER_VER_ID
- when /\A\d{4}-\d{2}-\d{2}\Z/
- v
- else
- raise "Invalid syntax in the version"
- end
- v = v.gsub(/-/, '')
hash_doc = begin
self.class.find_const("Provider_#{v}").new.document(request.ip)
rescue NameError => e
raise e if e.is_a? NoMethodError
@@ -66,11 +63,51 @@
else
raise "Unsupported format: .#{ext}"
end
end
- private
+ private
+ def get_data(params)
+ v = parse_version params[:version]
+
+ get_method = params[:data].gsub(/-/,'_')
+
+ provider = begin
+ self.class.find_const("Provider_#{v}").new
+ rescue NameError => e
+ raise e if e.is_a? NoMethodError
+ logger.error("ERROR: Unsupported metadata version: #{v}")
+ logger.error(e)
+ error(404, "Unsupported metadata version: #{v}")
+ rescue UnknownSourceIpError => e
+ error(404, "Unknown source IP: #{e.message}")
+ end
+
+ result = begin
+ provider.method(get_method).call(request.ip)
+ rescue NameError => e
+ raise e if e.is_a? NoMethodError
+ logger.error("ERROR: Unknown metadata: #{get_method}")
+ logger.error(e)
+ error(404, "Unknown metadata: #{get_method}")
+ end
+
+ result
+ end
+
+ def parse_version(v)
+ ret = case v
+ when 'latest'
+ LATEST_PROVIDER_VER_ID
+ when /\A\d{4}-\d{2}-\d{2}\Z/
+ v
+ else
+ raise "Invalid syntax in the version"
+ end
+ ret.gsub(/-/, '')
+ end
+
def shell_dump(hash)
# TODO: values to be shell escaped
hash.map {|k,v|
"#{k.to_s.upcase}='#{v}'"
}.join("\n")
@@ -98,32 +135,142 @@
# :ip=>'192.168.1.1',
# :name=>'xxxxxx'
# }]
# }
def document(src_ip)
+ inst = get_instance_from_ip(src_ip)
+ ret = {
+ :instance_id=>inst.canonical_uuid,
+ :cpu_cores=>inst.cpu_cores,
+ :memory_size=>inst.memory_size,
+ :state => inst.state,
+ :user_data=>inst.user_data.to_s,
+ }
+ # IP/network values
+ ret[:network] = inst.nic.map { |nic|
+ {:ip=>nic.ip.ipv4,
+ :name=>nic.ip.network.name,
+ }
+ }
+ ret[:volume] = inst.volume.map { |v|
+ }
+ ret
+ end
+
+ def get_instance_from_ip(src_ip)
ip = Models::IpLease.find(:ipv4=>src_ip)
if ip.nil? || ip.instance_nic.nil?
raise UnknownSourceIpError, src_ip
end
- inst = ip.instance_nic.instance
+ ip.instance_nic.instance
+ end
+ end
+
+ #This version implements compatibility with amazon EC2
+ class Provider_20110519 < Provider_20101101
+ def document(src_ip)
+ inst = get_instance_from_ip(src_ip)
ret = {
:instance_id=>inst.canonical_uuid,
:cpu_cores=>inst.cpu_cores,
:memory_size=>inst.memory_size,
:state => inst.state,
:user_data=>inst.user_data.to_s,
}
# IP/network values
ret[:network] = inst.nic.map { |nic|
- {:ip=>nic.ip.ipv4,
- :name=>nic.ip.network.name,
+ nic.ip.map { |ip|
+ {:ip=>ip.ipv4,
+ :uuid=>ip.network.canonical_uuid,
+ }
}
}
ret[:volume] = inst.volume.map { |v|
}
ret
end
- end
+ # EC2 Functions not implemented yet
+ # http://169.254.169.254/latest/meta-data/ami-launch-index
+ # http://169.254.169.254/latest/meta-data/ami-manifest-path
+ # http://169.254.169.254/latest/meta-data/ancestor-ami-ids
+ # http://169.254.169.254/latest/meta-data/block-device-mapping
+ # http://169.254.169.254/latest/meta-data/instance-type/instance-action
+ # http://169.254.169.254/latest/meta-data/instance-type
+ # http://169.254.169.254/latest/meta-data/kernel-id
+ # http://169.254.169.254/latest/meta-data/placement/availability-zone
+ # http://169.254.169.254/latest/meta-data/product-codes
+ # http://169.254.169.254/latest/meta-data/placement
+ # http://169.254.169.254/latest/meta-data/profile
+ # http://169.254.169.254/latest/meta-data/public-hostname
+ # http://169.254.169.254/latest/meta-data/ramdisk-id
+ # http://169.254.169.254/latest/meta-data/reservation-id
+ def wmi_id(src_ip)
+ get_instance_from_ip(src_ip).image.cuuid
+ end
+ alias ami_id wmi_id
+
+ def mac(src_ip)
+ get_instance_from_ip(src_ip).nic.map { |nic|
+ nic.pretty_mac_addr
+ }.join("\n")
+ end
+
+ def network(src_ip)
+ get_instance_from_ip(src_ip).nic.map { |nic|
+ nic.ip.map { |ip|
+ ip.network.cuuid
+ }
+ }.join("\n")
+ end
+
+ def instance_id(src_ip)
+ get_instance_from_ip(src_ip).cuuid
+ end
+
+ def local_hostname(src_ip)
+ get_instance_from_ip(src_ip).hostname
+ end
+
+ def local_ipv4(src_ip)
+ get_instance_from_ip(src_ip).nic.map { |nic|
+ nic.ip.map { |ip|
+ unless ip.is_natted?
+ ip.ipv4
+ else
+ nil
+ end
+ }.compact
+ }.join("\n")
+ end
+
+ def public_ipv4(src_ip)
+ get_instance_from_ip(src_ip).nic.map { |nic|
+ nic.ip.map { |ip|
+ if ip.is_natted?
+ ip.ipv4
+ else
+ nil
+ end
+ }.compact
+ }.join("\n")
+ end
+
+ def public_keys(src_ip)
+ i = get_instance_from_ip(src_ip)
+ # ssh_key_data is possible to be nil.
+ i.ssh_key_data.nil? ? '' : i.ssh_key_data[:public_key]
+ end
+
+ def security_groups(src_ip)
+ get_instance_from_ip(src_ip).netfilter_groups.map { |grp|
+ grp.name
+ }.join("\n")
+ end
+
+ def user_data(src_ip)
+ get_instance_from_ip(src_ip).user_data
+ end
+ end
end
end
end