1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-21 14:50:08 +03:00

feature #1383: Initial merge of the patch contributed by Ricardo Duarte to add support for EC2 Keypairs

This commit is contained in:
Ruben S. Montero 2012-09-25 19:52:24 +02:00
parent 985da96533
commit b3b18df5a2
9 changed files with 220 additions and 16 deletions

View File

@ -18,7 +18,12 @@ NIC=[NETWORK_ID=<EC2-VNET-ID>]
IMAGE_ID = <%= erb_vm_info[:ec2_img_id] %>
INSTANCE_TYPE = <%= erb_vm_info[:instance_type ]%>
<% if erb_vm_info[:user_data] %>
<% if erb_vm_info[:user_data] && erb_vm_info[:public_key] %>
CONTEXT = [ EC2_USER_DATA="<%= erb_vm_info[:user_data] %>", EC2_PUBLIC_KEY="<%= erb_vm_info[:public_key] %>", EC2_KEYNAME ="<%= erb_vm_info[:key_name] %>" ]
<% elsif erb_vm_info[:user_data] %>
CONTEXT = [ EC2_USER_DATA="<%= erb_vm_info[:user_data] %>" ]
<% elsif erb_vm_info[:public_key] %>
CONTEXT = [ EC2_PUBLIC_KEY="<%= erb_vm_info[:public_key] %>", EC2_KEYNAME ="<%= erb_vm_info[:key_name] %>" ]
<% end %>

View File

@ -17,14 +17,25 @@
require 'rubygems'
require 'erb'
require 'time'
require 'AWS'
require 'base64'
require 'CloudServer'
require 'json'
require 'openssl'
require 'digest/md5'
require 'AWS'
require 'CloudServer'
require 'ImageEC2'
require 'ebs'
require 'elastic_ip'
require 'instance'
require 'keypair'
################################################################################
# Extends the OpenNebula::Error class to include an EC2 render of error
# messages
################################################################################
module OpenNebula
EC2_ERROR = %q{
@ -54,12 +65,14 @@ end
###############################################################################
class EC2QueryServer < CloudServer
###########################################################################
############################################################################
#
#
############################################################################
def initialize(client, oneadmin_client, config, logger)
super(config, logger)
@client = client
@client = client
@oneadmin_client = oneadmin_client
if config[:ssl_server]
@ -68,12 +81,15 @@ class EC2QueryServer < CloudServer
@base_url="http://#{config[:server]}:#{config[:port]}"
end
# ----------- Load EC2 API modules ------------
if @config[:elasticips_vnet_id].nil?
logger.error { 'ElasticIP module not loaded' }
else
extend ElasticIP
end
extend Keypair
extend EBS
extend Instance
end
@ -83,8 +99,7 @@ class EC2QueryServer < CloudServer
###########################################################################
def describe_availability_zones(params)
response = ERB.new(
File.read(@config[:views]+"/describe_availability_zones.erb"))
response = ERB.new(File.read(@config[:views]+"/describe_availability_zones.erb"))
return response.result(binding), 200
end
@ -153,9 +168,8 @@ class EC2QueryServer < CloudServer
return response.result(binding), 200
end
###########################################################################
# Elastic IP
# Provide defaults for Elastic IP if not loaded
###########################################################################
def allocate_address(params)
return OpenNebula::Error.new('Unsupported')
@ -182,7 +196,6 @@ class EC2QueryServer < CloudServer
###########################################################################
private
def render_launch_time(vm)
return "<launchTime>#{Time.at(vm["STIME"].to_i).xmlschema}</launchTime>"
end

View File

@ -208,6 +208,12 @@ def do_http_request(params)
result,rc = @econe_server.detach_volume(params)
when 'DeleteVolume'
result,rc = @econe_server.delete_volume(params)
when 'DescribeKeyPairs'
result,rc = @econe_server.describe_keypairs(params)
when 'CreateKeyPair'
result,rc = @econe_server.create_keypair(params)
when 'DeleteKeyPair'
result,rc = @econe_server.delete_keypair(params)
else
result = OpenNebula::Error.new(
"#{params['Action']} feature is not supported",

View File

@ -59,15 +59,18 @@ module Instance
end
# Get the image
tmp, img=params['ImageId'].split('-')
tmp, img = params['ImageId'].split('-')
# Build the VM
erb_vm_info=Hash.new
erb_vm_info = Hash.new
erb_vm_info[:img_id] = img.to_i
erb_vm_info[:ec2_img_id] = params['ImageId']
erb_vm_info[:instance_type] = instance_type_name
erb_vm_info[:template] = path
erb_vm_info[:user_data] = params['UserData']
erb_vm_info[:public_key] = fetch_publickey(params)
erb_vm_info[:key_name] = params['KeyName']
template = ERB.new(File.read(erb_vm_info[:template]))
template_text = template.result(binding)
@ -184,4 +187,4 @@ module Instance
instance_id = "i-" + sprintf('%08i', vm.id)
return "<instanceId>#{instance_id}</instanceId>"
end
end
end

View File

@ -0,0 +1,153 @@
# -------------------------------------------------------------------------- #
# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
#--------------------------------------------------------------------------- #
module Keypair
############################################################################
# Extends the OpenNebula::User class to include Keypair management
############################################################################
class ::OpenNebula::User
EC2_KP_XPATH = '/USER/TEMPLATE/EC2_KEYPAIRS'
EC2_KP_ELEM = 'EC2_KEYPAIRS'
########################################################################
# Extracts a key pair for the user. Keypairs are stored in the user
# template as base64 json documents
# @param [OpenNebula::User] the user
#
# @return [Hash] with the keypairs. It may be empty
########################################################################
def add_keypair(keypairs)
kp = keypairs.to_json
kp64 = Base64.encode64(kp)
add_element('TEMPLATE', EC2_KP_ELEM => kp64)
return update(template_xml)
end
########################################################################
# Extracts a key pair for the user. Keypairs are stored in the user
# template as base64 json documents
# @param [OpenNebula::User] the user
#
# @return [Hash] with the keypairs. It may be empty
########################################################################
def get_keypair
if has_elements?(EC2_KP_XPATH)
kp64 = Base64.decode64(user[EC2_KP_XPATH])
kp = JSON.parse(kp64)
else
kp = Hash.new
end
return kp
end
end
############################################################################
# KeyPair managment functions for EC2 Query API Server
############################################################################
############################################################################
#
############################################################################
def create_keypair(params)
erb_version = params['Version']
erb_keyname = params['KeyName']
erb_user_name = params['AWSAccessKeyId']
user = User.new_with_id(OpenNebula::User::SELF, @client)
user.info
kp = user.get_keypair
rsa_kp = OpenSSL::PKey::RSA.generate(2048)
erb_private_key = rsa_kp
erb_public_key = rsa_kp.public_key
erb_key_fingerprint = Digest::MD5.hexdigest(rsa_kp.to_der).gsub(/(.{2})(?=.)/, '\1:\2')
kp[erb_keyname] = {
"fingerprint" => erb_key_fingerprint,
"public_key" => erb_public_key
}
rc = user.add_keypair(kp)
return rc if OpenNebula::is_error?(rc)
response = ERB.new(File.read(@config[:views]+"/create_keypair.erb"))
return response.result(binding), 200
end
############################################################################
#
############################################################################
def describe_keypairs(params)
erb_version = params['Version']
erb_user_name = params['AWSAccessKeyId']
user = User.new_with_id(OpenNebula::User::SELF, @client)
user.info
erb_keypairs = user.get_keypair
response = ERB.new(File.read(@config[:views]+"/describe_keypairs.erb"))
return response.result(binding), 200
end
############################################################################
#
############################################################################
def delete_keypair(params)
erb_version = params['Version']
erb_user_name = params['AWSAccessKeyId']
erb_key_name = params['KeyName']
erb_result = "false"
user = User.new_with_id(OpenNebula::User::SELF, @client)
user.info
kp = user.get_keypair
if !kp.empty?
kp.delete(erb_key_name)
rc = user.add_keypair(kp)
erb_result = "true" if !OpenNebula::is_error?(rc)
end
response = ERB.new(File.read(@config[:views]+"/delete_keypair.erb"))
return response.result(binding), 200
end
############################################################################
#
############################################################################
def fetch_publickey(params)
keyname = params['KeyName']
user = User.new_with_id(OpenNebula::User::SELF, @client)
user.info
kp = user.get_keypair
return nil if keyname.nil? || kp.empty? || kp[keyname].nil?
kp[keyname]['public_key']
end
end

View File

@ -0,0 +1,5 @@
<CreateKeyPairResponse xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>">
<keyName><%= erb_keyname %></keyName>
<keyFingerprint><%= erb_key_fingerprint %></keyFingerprint>
<keyMaterial><%= erb_private_key %></keyMaterial>
</CreateKeyPairResponse>

View File

@ -0,0 +1,4 @@
<?xml version="1.0"?>
<DeleteKeyPair xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>">
<return><%= erb_result %></return>
</DeleteKeyPair>

View File

@ -20,7 +20,11 @@
</instanceState>
<privateDnsName><%= vm["TEMPLATE/NIC/IP"] %></privateDnsName>
<dnsName><%= vm["TEMPLATE/NIC/IP"] %></dnsName>
<keyName>default</keyName>
<% if vm['TEMPLATE/CONTEXT/EC2_KEYNAME'].nil? %>
<keyName>none</keyName>
<% else %>
<keyName><%= vm['TEMPLATE/CONTEXT/EC2_KEYNAME'] %></keyName>
<% end %>
<amiLaunchIndex>0</amiLaunchIndex>
<productCodes/>
<instanceType><%= vm['TEMPLATE/INSTANCE_TYPE'] %></instanceType>

View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<DescribeKeyPairsResponse xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>/">
<keySet>
<% erb_keypairs.each_pair do |k,v| %>
<item>
<keyName><%= k %></keyName>
<keyFingerprint><%= v['fingerprint'] %></keyFingerprint>
</item>
<% end %>
</keySet>
</DescribeKeyPairsResponse>