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:
parent
985da96533
commit
b3b18df5a2
@ -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 %>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
|
153
src/cloud/ec2/lib/keypair.rb
Normal file
153
src/cloud/ec2/lib/keypair.rb
Normal 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
|
5
src/cloud/ec2/lib/views/create_keypair.erb
Normal file
5
src/cloud/ec2/lib/views/create_keypair.erb
Normal 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>
|
4
src/cloud/ec2/lib/views/delete_keypair.erb
Normal file
4
src/cloud/ec2/lib/views/delete_keypair.erb
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0"?>
|
||||
<DeleteKeyPair xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>">
|
||||
<return><%= erb_result %></return>
|
||||
</DeleteKeyPair>
|
@ -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>
|
||||
|
11
src/cloud/ec2/lib/views/describe_keypairs.erb
Normal file
11
src/cloud/ec2/lib/views/describe_keypairs.erb
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user