1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-23 22:50:09 +03:00

feature #3652: Extend Onegate with self-awareness and self-configuration actions

This commit is contained in:
Daniel Molina 2015-04-06 17:36:49 +02:00
parent 04a97cc751
commit 7cb7c8c54d

View File

@ -137,6 +137,20 @@ helpers do
service.body
end
def parse_json(json_str, root_element)
begin
hash = JSON.parse(json_str)
rescue Exception => e
return OpenNebula::Error.new(e.message)
end
if hash.has_key?(root_element)
return hash[root_element]
else
return OpenNebula::Error.new("Error parsing JSON: Wrong resource type")
end
end
end
NIC_VALID_KEYS = %w(IP IP6_LINK IP6_SITE IP6_GLOBAL NETWORK MAC)
@ -155,6 +169,8 @@ def build_vm_hash(vm_hash)
"VM" => {
"NAME" => vm_hash["NAME"],
"ID" => vm_hash["ID"],
"STATE" => vm_hash["STATE"],
"LCM_STATE" => vm_hash["LCM_STATE"],
"USER_TEMPLATE" => Hash[vm_hash["USER_TEMPLATE"].select {|k,v|
!USER_TEMPLATE_INVALID_KEYS.include?(k)
}],
@ -175,6 +191,7 @@ def build_service_hash(service_hash)
service_info = {
"name" => service_hash["DOCUMENT"]["NAME"],
"id" => service_hash["DOCUMENT"]["ID"],
"state" => service_hash["DOCUMENT"]["TEMPLATE"]["BODY"]["state"],
"roles" => []
}
@ -294,11 +311,184 @@ get '/service' do
[200, response.to_json]
end
get '/vms/:id' do
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
source_vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
requested_vm_id = params[:id].to_i
vm = get_vm(source_vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{source_vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(requested_vm_id)
error_msg = "VMID:#{requested_vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
vm = get_vm(requested_vm_id, client)
response = build_vm_hash(vm.to_hash["VM"])
[200, response.to_json]
end
post '/vms/:id/action' do
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
source_vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
requested_vm_id = params[:id].to_i
vm = get_vm(source_vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{source_vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(requested_vm_id)
error_msg = "VMID:#{requested_vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
vm = get_vm(requested_vm_id, client)
action_hash = parse_json(request.body.read, 'action')
if OpenNebula.is_error?(action_hash)
halt 400, rc.message
end
rc = case action_hash['perform']
when "deploy" then vm.deploy(action_hash['params'])
when "delete" then vm.finalize
when "hold" then vm.hold
when "livemigrate" then vm.migrate(action_hash['params'], true)
when "migrate" then vm.migrate(action_hash['params'], false)
when "resume" then vm.resume
when "release" then vm.release
when "stop" then vm.stop
when "suspend" then vm.suspend
when "saveas" then vm.save_as(action_hash['params'])
when "snapshot_create" then vm.snapshot_create(action_hash['params'])
when "snapshot_revert" then vm.snapshot_revert(action_hash['params'])
when "snapshot_delete" then vm.snapshot_delete(action_hash['params'])
when "shutdown" then vm.shutdown(action_hash['params'])
when "reboot" then vm.reboot(action_hash['params'])
when "poweroff" then vm.poweroff(action_hash['params'])
when "resubmit" then vm.resubmit
when "chown" then vm.chown(action_hash['params'])
when "chmod" then vm.chmod_octet(action_hash['params'])
when "resize" then vm.resize(action_hash['params'])
when "attachdisk" then vm.disk_attach(action_hash['params'])
when "detachdisk" then vm.disk_detach(action_hash['params'])
when "attachnic" then vm.nic_attach(action_hash['params'])
when "detachnic" then vm.nic_detach(action_hash['params'])
when "update" then vm.update(action_hash['params'])
when "rename" then vm.rename(action_hash['params'])
when "undeploy" then vm.undeploy(action_hash['params'])
when "resched" then vm.resched
when "unresched" then vm.unresched
when "recover" then vm.recover(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
if OpenNebula.is_error?(rc)
halt 500, rc.message
else
[204, vm.to_json]
end
end
put '/service/role/:role' do
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?
vm_id = request.env['HTTP_X_ONEGATE_VMID'].to_i
vm = get_vm(vm_id, client)
service_id = vm['USER_TEMPLATE/SERVICE_ID']
service = get_service(service_id, client)
service_hash = JSON.parse(service)
response = build_service_hash(service_hash) rescue nil
if response.nil?
error_msg = "VMID:#{vm_id} Service #{service_id} is empty."
logger.error {error_msg}
halt 400, error_msg
end
# Check that the user has not spoofed the Service_ID
service_vm_ids = response["SERVICE"]["roles"].collect do |r|
r["nodes"].collect{|n| n["deploy_id"]}
end.flatten rescue []
if service_vm_ids.empty? || !service_vm_ids.include?(vm_id)
error_msg = "VMID:#{vm_id} Service #{service_id} does not contain VM."
logger.error {error_msg}
halt 400, error_msg
end
action_response = flow_client(client).put(
"/service/" + service_id + "/role/" + params[:role],
request.body.read)
if CloudClient::is_error?(action_response)
error_msg = "Error performing action on service #{service_id} role #{params[:role]}"
logger.error {error_msg}
logger.error {action_response.message}
halt 400, error_msg
end
[200, ""]
end
#############
# DEPRECATED
#############
put '/vm/:id' do
put '/vms/:id' do
client = authenticate(request.env, params)
halt 401, "Not authorized" if client.nil?