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:
parent
04a97cc751
commit
7cb7c8c54d
@ -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?
|
||||
|
Loading…
x
Reference in New Issue
Block a user