mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-01 06:50:25 +03:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
cb40cc21ee
@ -1011,6 +1011,7 @@ CLOUD_AUTH_LIB_FILES="src/cloud/common/CloudAuth/OCCICloudAuth.rb \
|
||||
ECO_LIB_FILES="src/cloud/ec2/lib/EC2QueryClient.rb \
|
||||
src/cloud/ec2/lib/EC2QueryServer.rb \
|
||||
src/cloud/ec2/lib/ImageEC2.rb \
|
||||
src/cloud/ec2/lib/elastic_ip.rb \
|
||||
src/cloud/ec2/lib/econe-server.rb"
|
||||
|
||||
ECO_LIB_CLIENT_FILES="src/cloud/ec2/lib/EC2QueryClient.rb"
|
||||
@ -1019,6 +1020,11 @@ ECO_LIB_VIEW_FILES="src/cloud/ec2/lib/views/describe_images.erb \
|
||||
src/cloud/ec2/lib/views/describe_instances.erb \
|
||||
src/cloud/ec2/lib/views/register_image.erb \
|
||||
src/cloud/ec2/lib/views/run_instances.erb \
|
||||
src/cloud/ec2/lib/views/allocate_address.erb \
|
||||
src/cloud/ec2/lib/views/associate_address.erb \
|
||||
src/cloud/ec2/lib/views/disassociate_address.erb \
|
||||
src/cloud/ec2/lib/views/describe_addresses.erb \
|
||||
src/cloud/ec2/lib/views/release_address.erb \
|
||||
src/cloud/ec2/lib/views/terminate_instances.erb"
|
||||
|
||||
ECO_BIN_FILES="src/cloud/ec2/bin/econe-server \
|
||||
|
@ -17,6 +17,8 @@
|
||||
require 'sequel'
|
||||
require 'base64'
|
||||
require 'yaml'
|
||||
require 'uri'
|
||||
require 'net/http'
|
||||
|
||||
class Quota
|
||||
###########################################################################
|
||||
@ -82,7 +84,15 @@ class Quota
|
||||
if template['TYPE'] == 'DATABLOCK'
|
||||
template['SIZE'].to_i
|
||||
elsif template['PATH']
|
||||
(File.size(template['PATH']).to_f / 2**20).round
|
||||
uri = URI.parse(template['PATH'])
|
||||
size = if uri.scheme.nil?
|
||||
File.size(template['PATH'])
|
||||
else
|
||||
Net::HTTP.start(uri.host,uri.port) { |http|
|
||||
http.head(uri.path)
|
||||
}.content_length
|
||||
end
|
||||
(size.to_f / 2**20).round
|
||||
elsif template['SAVED_VM_ID']
|
||||
vm_id = template['SAVED_VM_ID'].to_i
|
||||
disk_id = template['SAVED_DISK_ID'].to_i
|
||||
|
@ -37,9 +37,20 @@
|
||||
# 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
:debug_level: 3
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
:cluster_id:
|
||||
:datastore_id:
|
||||
|
||||
#
|
||||
#
|
||||
#
|
||||
:elasticips_vnet_id: 0
|
||||
|
||||
:associate_script: /usr/bin/false
|
||||
:disassociate_script: /usr/bin/false
|
||||
|
||||
# VM types allowed and its template file (inside templates directory)
|
||||
:instance_types:
|
||||
:m1.small:
|
||||
|
@ -61,10 +61,18 @@ class EC2QueryServer < CloudServer
|
||||
|
||||
###########################################################################
|
||||
|
||||
def initialize(client, config, logger)
|
||||
def initialize(client, oneadmin_client, config, logger)
|
||||
super(config, logger)
|
||||
|
||||
@client = client
|
||||
@oneadmin_client = oneadmin_client
|
||||
|
||||
if @config[:elasticips_vnet_id].nil?
|
||||
logger.error { 'ElasticIP module not loaded' }
|
||||
else
|
||||
require 'elastic_ip'
|
||||
extend ElasticIP
|
||||
end
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
@ -207,9 +215,34 @@ class EC2QueryServer < CloudServer
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Elastic IP
|
||||
###########################################################################
|
||||
def allocate_address(params)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
def release_address(params)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
def describe_addresses(params)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
def associate_address(params)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
def disassociate_address(params)
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Helper functions
|
||||
###########################################################################
|
||||
private
|
||||
|
||||
def render_state(vm)
|
||||
one_state = ONE_STATES[vm.status]
|
||||
ec2_state = EC2_STATES[one_state||:pending]
|
||||
|
@ -135,8 +135,9 @@ before do
|
||||
if username.nil?
|
||||
error 401, error_xml("AuthFailure", 0)
|
||||
else
|
||||
client = settings.cloud_auth.client(username)
|
||||
@econe_server = EC2QueryServer.new(client, settings.config, settings.logger)
|
||||
client = settings.cloud_auth.client(username)
|
||||
oneadmin_client = settings.cloud_auth.client
|
||||
@econe_server = EC2QueryServer.new(client, oneadmin_client, settings.config, settings.logger)
|
||||
end
|
||||
end
|
||||
|
||||
@ -189,6 +190,16 @@ def do_http_request(params)
|
||||
result,rc = @econe_server.describe_instances(params)
|
||||
when 'TerminateInstances'
|
||||
result,rc = @econe_server.terminate_instances(params)
|
||||
when 'AllocateAddress'
|
||||
result,rc = @econe_server.allocate_address(params)
|
||||
when 'AssociateAddress'
|
||||
result,rc = @econe_server.associate_address(params)
|
||||
when 'DisassociateAddress'
|
||||
result,rc = @econe_server.disassociate_address(params)
|
||||
when 'ReleaseAddress'
|
||||
result,rc = @econe_server.release_address(params)
|
||||
when 'DescribeAddresses'
|
||||
result,rc = @econe_server.describe_addresses(params)
|
||||
end
|
||||
|
||||
if OpenNebula::is_error?(result)
|
||||
|
198
src/cloud/ec2/lib/elastic_ip.rb
Normal file
198
src/cloud/ec2/lib/elastic_ip.rb
Normal file
@ -0,0 +1,198 @@
|
||||
module ElasticIP
|
||||
def allocate_address(params)
|
||||
# Get public IP
|
||||
vnet = retrieve_eip_vnet
|
||||
return vnet, 400 if OpenNebula::is_error?(vnet)
|
||||
|
||||
ips = vnet.retrieve_elements('LEASES/LEASE[USED=0]/IP')
|
||||
if ips.nil?
|
||||
logger.error { "There is no lease available to be allocated" }
|
||||
return OpenNebula::Error.new('AddressLimitExceeded'), 400
|
||||
end
|
||||
|
||||
eip = ips.first
|
||||
|
||||
# Hold IP
|
||||
rc = vnet.hold(eip)
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error rc.message
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Update EC2_ADDRESSES list
|
||||
xml_hash = {'EC2_ADDRESSES' => {'IP' => eip, "UID" => retrieve_uid}}
|
||||
vnet.add_element('TEMPLATE', xml_hash)
|
||||
rc = vnet.update
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error rc.message
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
response = ERB.new(File.read(@config[:views]+"/allocate_address.erb"))
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
def release_address(params)
|
||||
# Check public IP
|
||||
vnet = retrieve_eip_vnet
|
||||
return vnet, 400 if OpenNebula::is_error?(vnet)
|
||||
|
||||
eip = params["PublicIp"]
|
||||
unless vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\" and UID=\"#{retrieve_uid}\"]/IP"]
|
||||
logger.error { "address:#{eip} does not exist" }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Disassociate address if needed
|
||||
if vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]/VMID"]
|
||||
cmd_output = `#{@config[:disassociate_script]} #{eip}`
|
||||
if $?.to_i != 0
|
||||
logger.error { cmd_output }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
vnet.delete_element("TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]/VMID")
|
||||
end
|
||||
|
||||
# Release IP
|
||||
rc = vnet.release(eip)
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Update EC2_ADDRESSES list
|
||||
vnet.delete_element("TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]")
|
||||
rc = vnet.update
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
response = ERB.new(File.read(@config[:views]+"/release_address.erb"))
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
def describe_addresses(params)
|
||||
vnet = retrieve_eip_vnet
|
||||
return vnet, 400 if OpenNebula::is_error?(vnet)
|
||||
|
||||
erb_version = params['Version']
|
||||
user_id = retrieve_uid
|
||||
|
||||
response = ERB.new(File.read(@config[:views]+"/describe_addresses.erb"))
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
def associate_address(params)
|
||||
# Check public IP
|
||||
vnet = retrieve_eip_vnet
|
||||
return vnet, 400 if OpenNebula::is_error?(vnet)
|
||||
|
||||
user_id = retrieve_uid
|
||||
eip = params["PublicIp"]
|
||||
vmid = params['InstanceId']
|
||||
vmid = vmid.split('-')[1] if vmid[0]==?i
|
||||
|
||||
unless vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\" and UID=\"#{retrieve_uid}\"]/IP"]
|
||||
logger.error { "address:#{eip} does not exist" }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Get private IP of the Instance
|
||||
vm = VirtualMachine.new(VirtualMachine.build_xml(vmid), @client)
|
||||
rc = vm.info
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
ips = vm.retrieve_elements('TEMPLATE/NIC/IP')
|
||||
if ips.nil?
|
||||
logger.error { "The instance does not have any NIC" }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
private_ip = ips.first
|
||||
|
||||
# Disassociate address if needed
|
||||
if vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]/VMID"]
|
||||
cmd_output = `#{@config[:disassociate_script]} #{eip}`
|
||||
if $?.to_i != 0
|
||||
logger.error { cmd_output }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
vnet.delete_element("TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]/VMID")
|
||||
end
|
||||
|
||||
# Run external script
|
||||
vnet_base64 = Base64.encode64(vnet.to_xml).delete("\n")
|
||||
cmd_output = `#{@config[:associate_script]} #{eip} #{private_ip} \"#{vnet_base64}\"`
|
||||
if $?.to_i != 0
|
||||
logger.error { "associate_script" << cmd_output }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Update EC2_ADDRESSES list
|
||||
vnet.add_element("TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]", "VMID" => vmid)
|
||||
rc = vnet.update
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
response = ERB.new(File.read(@config[:views]+"/associate_address.erb"))
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
def disassociate_address(params)
|
||||
# Check public IP
|
||||
vnet = retrieve_eip_vnet
|
||||
return vnet, 400 if OpenNebula::is_error?(vnet)
|
||||
|
||||
eip = params["PublicIp"]
|
||||
unless vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\" and UID=\"#{retrieve_uid}\"]/VMID"]
|
||||
logger.error { "address:#{eip} does not exist or is not associated with any instance" }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Run external script
|
||||
cmd_output = `#{@config[:disassociate_script]} #{eip}`
|
||||
if $?.to_i != 0
|
||||
logger.error { cmd_output }
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
# Update EC2_ADDRESSES list
|
||||
vnet.delete_element("TEMPLATE/EC2_ADDRESSES[IP=\"#{eip}\"]/VMID")
|
||||
rc = vnet.update
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported'),400
|
||||
end
|
||||
|
||||
response = ERB.new(File.read(@config[:views]+"/disassociate_address.erb"))
|
||||
return response.result(binding), 200
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def retrieve_eip_vnet
|
||||
vnet = VirtualNetwork.new(VirtualNetwork.build_xml(@config[:elasticips_vnet_id]),@oneadmin_client)
|
||||
rc = vnet.info
|
||||
|
||||
if OpenNebula::is_error?(rc)
|
||||
logger.error {rc.message}
|
||||
return OpenNebula::Error.new('Unsupported')
|
||||
end
|
||||
|
||||
vnet
|
||||
end
|
||||
|
||||
def retrieve_uid
|
||||
user = User.new_with_id(OpenNebula::User::SELF, @client)
|
||||
user.info
|
||||
user.id
|
||||
end
|
||||
end
|
8
src/cloud/ec2/lib/views/allocate_address.erb
Normal file
8
src/cloud/ec2/lib/views/allocate_address.erb
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<AllocateAddressResponse xmlns="http://ec2.amazonaws.com/doc/<%= params['Version'] %>/">
|
||||
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
|
||||
<publicIp><%= eip %></publicIp>
|
||||
<domain>standard</domain>
|
||||
<allocationId>9090909090</allocationId>
|
||||
|
||||
</AllocateAddressResponse>
|
6
src/cloud/ec2/lib/views/associate_address.erb
Normal file
6
src/cloud/ec2/lib/views/associate_address.erb
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<AssociateAddressResponse xmlns="http://ec2.amazonaws.com/doc/<%= params['Version'] %>/">
|
||||
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
|
||||
<return>true</return>
|
||||
<associationId/>
|
||||
</AssociateAddressResponse>
|
21
src/cloud/ec2/lib/views/describe_addresses.erb
Normal file
21
src/cloud/ec2/lib/views/describe_addresses.erb
Normal file
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0"?>
|
||||
<DescribeAddressesResponse xmlns="http://ec2.amazonaws.com/doc/<%= erb_version %>/">
|
||||
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
|
||||
<addressesSet>
|
||||
<% vnet.each("LEASES/LEASE[USED=1 and VID=-1]") do |eip| %>
|
||||
<% if vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip["IP"]}\"]/UID"] == user_id.to_s %>
|
||||
<item>
|
||||
<publicIp><%= eip["IP"] %></publicIp>
|
||||
<domain>standard</domain>
|
||||
<% if vm_id = vnet["TEMPLATE/EC2_ADDRESSES[IP=\"#{eip["IP"]}\"]/VMID"] %>
|
||||
<instanceId><%= vm_id %></instanceId>
|
||||
<% else %>
|
||||
<instanceId/>
|
||||
<% end %>
|
||||
<associationId/>
|
||||
<allocationId/>
|
||||
</item>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</addressesSet>
|
||||
</DescribeAddressesResponse>
|
@ -2,7 +2,6 @@
|
||||
<DescribeImagesResponse xmlns="http://ec2.amazonaws.com/doc/<%=erb_version%>/">
|
||||
<imagesSet>
|
||||
<% impool.each do |im| %>
|
||||
<% im.info %>
|
||||
<item>
|
||||
<imageId>ami-<%= sprintf('%08i', im.id) %></imageId>
|
||||
<imageLocation><%= im['SOURCE'].split('/').last %></imageLocation>
|
||||
|
6
src/cloud/ec2/lib/views/disassociate_address.erb
Normal file
6
src/cloud/ec2/lib/views/disassociate_address.erb
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0"?>
|
||||
<ReleaseAddressResponse xmlns="http://ec2.amazonaws.com/doc/<%= params['Version'] %>/">
|
||||
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
|
||||
<return>true</return>
|
||||
</ReleaseAddressResponse>
|
||||
|
5
src/cloud/ec2/lib/views/release_address.erb
Normal file
5
src/cloud/ec2/lib/views/release_address.erb
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0"?>
|
||||
<ReleaseAddressResponse xmlns="http://ec2.amazonaws.com/doc/<%= params['Version'] %>/">
|
||||
<requestId>4ac62eaf-e266-4058-a970-2c01568cd417</requestId>
|
||||
<return>true</return>
|
||||
</ReleaseAddressResponse>
|
@ -161,7 +161,7 @@ var OCCI = {
|
||||
});
|
||||
},
|
||||
|
||||
"delete": function(params,resource){
|
||||
"del": function(params,resource){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
@ -373,8 +373,8 @@ var OCCI = {
|
||||
"create": function(params){
|
||||
OCCI.Action.create(params,OCCI.Network.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OCCI.Action.delete(params,OCCI.Network.resource);
|
||||
"del": function(params){
|
||||
OCCI.Action.del(params,OCCI.Network.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OCCI.Action.list(params,OCCI.Network.resource);
|
||||
@ -398,8 +398,8 @@ var OCCI = {
|
||||
"create": function(params){
|
||||
OCCI.Action.create(params,OCCI.VM.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OCCI.Action.delete(params,OCCI.VM.resource);
|
||||
"del": function(params){
|
||||
OCCI.Action.del(params,OCCI.VM.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OCCI.Action.list(params,OCCI.VM.resource);
|
||||
@ -502,8 +502,8 @@ var OCCI = {
|
||||
}
|
||||
});
|
||||
},
|
||||
"delete": function(params){
|
||||
OCCI.Action.delete(params,OCCI.Image.resource);
|
||||
"del": function(params){
|
||||
OCCI.Action.del(params,OCCI.Image.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OCCI.Action.list(params,OCCI.Image.resource);
|
||||
@ -535,8 +535,8 @@ var OCCI = {
|
||||
"create" : function(params){
|
||||
OCCI.Action.create(params,OCCI.Template.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
OCCI.Action.delete(params,OCCI.Template.resource);
|
||||
"del" : function(params){
|
||||
OCCI.Action.del(params,OCCI.Template.resource);
|
||||
},
|
||||
"list" : function(params){
|
||||
OCCI.Action.list(params,OCCI.Template.resource);
|
||||
|
@ -143,7 +143,7 @@ var vnet_actions = {
|
||||
|
||||
"Network.delete" : {
|
||||
type: "multiple",
|
||||
call: OCCI.Network.delete,
|
||||
call: OCCI.Network.del,
|
||||
callback: deleteVNetworkElement,
|
||||
elements: vnElements,
|
||||
error: onError,
|
||||
|
@ -199,7 +199,7 @@ var image_actions = {
|
||||
|
||||
"Image.delete" : {
|
||||
type: "multiple",
|
||||
call: OCCI.Image.delete,
|
||||
call: OCCI.Image.del,
|
||||
callback: deleteImageElement,
|
||||
elements: imageElements,
|
||||
error: onError,
|
||||
|
@ -178,6 +178,8 @@ module OpenNebula
|
||||
def update(xml_method, new_template)
|
||||
return Error.new('ID not defined') if !@pe_id
|
||||
|
||||
new_template ||= template_xml.delete("\n").gsub(/\s+/m,'')
|
||||
|
||||
rc = @client.call(xml_method,@pe_id, new_template)
|
||||
rc = nil if !OpenNebula.is_error?(rc)
|
||||
|
||||
|
@ -90,7 +90,7 @@ module OpenNebula
|
||||
# Replaces the template contents
|
||||
#
|
||||
# +new_template+ New template contents
|
||||
def update(new_template)
|
||||
def update(new_template=nil)
|
||||
super(VN_METHODS[:update], new_template)
|
||||
end
|
||||
|
||||
|
@ -101,6 +101,44 @@ module OpenNebula
|
||||
end
|
||||
end
|
||||
|
||||
def delete_element(xpath)
|
||||
if NOKOGIRI
|
||||
@xml.xpath(xpath.to_s).remove
|
||||
else
|
||||
@xml.delete_element(xpath.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def add_element(xpath, elems)
|
||||
elems.each { |key, value|
|
||||
if value.instance_of?(Hash)
|
||||
if NOKOGIRI
|
||||
elem = Nokogiri::XML::Node.new key, @xml.document
|
||||
value.each { |k2, v2|
|
||||
child = Nokogiri::XML::Node.new k2, elem
|
||||
child.content = v2
|
||||
elem.add_child(child)
|
||||
}
|
||||
@xml.xpath(xpath.to_s).first.add_child(elem)
|
||||
else
|
||||
elem = REXML::Element.new(key)
|
||||
value.each { |k2, v2|
|
||||
elem.add_element(k2).text = v2
|
||||
}
|
||||
@xml.elements[xpath].add_element(elem)
|
||||
end
|
||||
else
|
||||
if NOKOGIRI
|
||||
elem = Nokogiri::XML::Node.new key, @xml.document
|
||||
elem.content = value
|
||||
@xml.xpath(xpath.to_s).first.add_child(elem)
|
||||
else
|
||||
@xml.elements[xpath].add_element(key).text = value
|
||||
end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Gets an array of text from elemenets extracted
|
||||
# using the XPATH expression passed as filter
|
||||
def retrieve_elements(filter)
|
||||
@ -201,6 +239,14 @@ module OpenNebula
|
||||
template_like_str('TEMPLATE', indent)
|
||||
end
|
||||
|
||||
def template_xml
|
||||
if NOKOGIRI
|
||||
@xml.xpath('TEMPLATE').to_s
|
||||
else
|
||||
@xml.elements['TEMPLATE'].to_s
|
||||
end
|
||||
end
|
||||
|
||||
def template_like_str(root_element, indent=true, xpath_exp=nil)
|
||||
if NOKOGIRI
|
||||
xml_template=@xml.xpath(root_element).to_s
|
||||
|
@ -223,7 +223,7 @@ var oZones = {
|
||||
});
|
||||
},
|
||||
|
||||
"delete": function(params,resource){
|
||||
"del": function(params,resource){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
@ -381,8 +381,8 @@ var oZones = {
|
||||
"create": function(params){
|
||||
oZones.Action.create(params,oZones.Zone.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
oZones.Action.delete(params,oZones.Zone.resource);
|
||||
"del" : function(params){
|
||||
oZones.Action.del(params,oZones.Zone.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
oZones.Action.list(params,oZones.Zone.resource);
|
||||
@ -446,8 +446,8 @@ var oZones = {
|
||||
"update": function(params){
|
||||
oZones.Action.update(params,oZones.VDC.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
oZones.Action.delete(params,oZones.VDC.resource);
|
||||
"del": function(params){
|
||||
oZones.Action.del(params,oZones.VDC.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
oZones.Action.list(params,oZones.VDC.resource);
|
||||
|
@ -155,7 +155,7 @@ var vdc_actions = {
|
||||
|
||||
"VDC.delete" : {
|
||||
type: "multiple",
|
||||
call: oZones.VDC.delete,
|
||||
call: oZones.VDC.del,
|
||||
callback: deleteVDCElement,
|
||||
elements: vdcSelectedNodes,
|
||||
error: onError,
|
||||
|
@ -118,7 +118,7 @@ var zone_actions = {
|
||||
|
||||
"Zone.delete" : {
|
||||
type: "multiple",
|
||||
call: oZones.Zone.delete,
|
||||
call: oZones.Zone.del,
|
||||
callback: deleteZoneElement,
|
||||
elements: zoneSelectedNodes,
|
||||
error: onError,
|
||||
|
@ -53,11 +53,15 @@
|
||||
:ALL: true
|
||||
:user:
|
||||
:group:
|
||||
- plugins/hosts-tab.js:
|
||||
- plugins/clusters-tab.js:
|
||||
:ALL: false
|
||||
:user:
|
||||
:group:
|
||||
oneadmin: true
|
||||
- plugins/hosts-tab.js:
|
||||
:ALL: true
|
||||
:user:
|
||||
:group:
|
||||
- plugins/datastores-tab.js:
|
||||
:ALL: true
|
||||
:user:
|
||||
@ -66,8 +70,3 @@
|
||||
:ALL: true
|
||||
:user:
|
||||
:group:
|
||||
- plugins/clusters-tab.js:
|
||||
:ALL: false
|
||||
:user:
|
||||
:group:
|
||||
oneadmin: true
|
||||
|
@ -46,21 +46,24 @@ var OpenNebula = {
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case "HOST","host":
|
||||
case "HOST":
|
||||
case "host":
|
||||
return ["INIT",
|
||||
"MONITORING",
|
||||
"MONITORED",
|
||||
"ERROR",
|
||||
"DISABLED"][value];
|
||||
break;
|
||||
case "HOST_SIMPLE","host_simple":
|
||||
case "HOST_SIMPLE":
|
||||
case "host_simple":
|
||||
return ["ON",
|
||||
"ON",
|
||||
"ON",
|
||||
"ERROR",
|
||||
"OFF"][value];
|
||||
break;
|
||||
case "VM","vm":
|
||||
case "VM":
|
||||
case "vm":
|
||||
return ["INIT",
|
||||
"PENDING",
|
||||
"HOLD",
|
||||
@ -70,7 +73,8 @@ var OpenNebula = {
|
||||
"DONE",
|
||||
"FAILED"][value];
|
||||
break;
|
||||
case "VM_LCM","vm_lcm":
|
||||
case "VM_LCM":
|
||||
case "vm_lcm":
|
||||
return ["LCM_INIT",
|
||||
"PROLOG",
|
||||
"BOOT",
|
||||
@ -89,7 +93,8 @@ var OpenNebula = {
|
||||
"CLEANUP",
|
||||
"UNKNOWN"][value];
|
||||
break;
|
||||
case "IMAGE","image":
|
||||
case "IMAGE":
|
||||
case "image":
|
||||
return ["INIT",
|
||||
"READY",
|
||||
"USED",
|
||||
@ -97,6 +102,14 @@ var OpenNebula = {
|
||||
"LOCKED",
|
||||
"ERROR"][value];
|
||||
break;
|
||||
case "VM_MIGRATE_REASON":
|
||||
case "vm_migrate_reason":
|
||||
return ["NONE",
|
||||
"ERROR",
|
||||
"STOP_RESUME",
|
||||
"USER",
|
||||
"CANCEL"][value];
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@ -203,7 +216,7 @@ var OpenNebula = {
|
||||
});
|
||||
},
|
||||
|
||||
"delete": function(params,resource){
|
||||
"del": function(params,resource){
|
||||
var callback = params.success;
|
||||
var callback_error = params.error;
|
||||
var id = params.data.id;
|
||||
@ -437,8 +450,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Host.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Host.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Host.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Host.resource);
|
||||
@ -476,8 +489,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Network.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Network.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Network.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Network.resource);
|
||||
@ -550,8 +563,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.VM.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.VM.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.VM.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.VM.resource);
|
||||
@ -668,8 +681,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Group.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Group.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Group.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Group.resource);
|
||||
@ -682,8 +695,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.User.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.User.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.User.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.User.resource);
|
||||
@ -734,8 +747,8 @@ var OpenNebula = {
|
||||
"create": function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Image.resource);
|
||||
},
|
||||
"delete": function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Image.resource);
|
||||
"del": function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Image.resource);
|
||||
},
|
||||
"list": function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Image.resource);
|
||||
@ -793,8 +806,8 @@ var OpenNebula = {
|
||||
"create" : function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Template.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Template.resource);
|
||||
"del" : function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Template.resource);
|
||||
},
|
||||
"list" : function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Template.resource);
|
||||
@ -846,8 +859,8 @@ var OpenNebula = {
|
||||
"create" : function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Acl.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Acl.resource);
|
||||
"del" : function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Acl.resource);
|
||||
},
|
||||
"list" : function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Acl.resource);
|
||||
@ -860,8 +873,8 @@ var OpenNebula = {
|
||||
"create" : function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Cluster.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Cluster.resource);
|
||||
"del" : function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Cluster.resource);
|
||||
},
|
||||
"list" : function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Cluster.resource);
|
||||
@ -906,8 +919,8 @@ var OpenNebula = {
|
||||
"create" : function(params){
|
||||
OpenNebula.Action.create(params,OpenNebula.Datastore.resource);
|
||||
},
|
||||
"delete" : function(params){
|
||||
OpenNebula.Action.delete(params,OpenNebula.Datastore.resource);
|
||||
"del" : function(params){
|
||||
OpenNebula.Action.del(params,OpenNebula.Datastore.resource);
|
||||
},
|
||||
"list" : function(params){
|
||||
OpenNebula.Action.list(params,OpenNebula.Datastore.resource);
|
||||
|
@ -129,7 +129,7 @@ var acl_actions = {
|
||||
|
||||
"Acl.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Acl.delete,
|
||||
call: OpenNebula.Acl.del,
|
||||
callback: deleteAclElement,
|
||||
elements: aclElements,
|
||||
error: onError,
|
||||
|
@ -166,7 +166,7 @@ var cluster_actions = {
|
||||
|
||||
"Cluster.delete" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Cluster.delete,
|
||||
call : OpenNebula.Cluster.del,
|
||||
callback : deleteClusterElement,
|
||||
elements: clusterElements,
|
||||
error : onError,
|
||||
@ -366,7 +366,82 @@ function clusterTabContent(cluster_json) {
|
||||
vnets_list = '<li class="clusterElemLi">'+cluster.VNETS.ID+' - '+getVNetName(cluster.VNETS.ID)+'</li>';
|
||||
*/
|
||||
|
||||
//special case for cluster none, simplified dashboard
|
||||
if (cluster.ID == "-"){
|
||||
var html_code = '\
|
||||
<table class="dashboard_table">\
|
||||
<tr>\
|
||||
<td style="width:50%">\
|
||||
<table style="width:100%">\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3>' + tr("Cluster information") + '</h3>\
|
||||
<div class="panel_info">\
|
||||
\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<td class="key_td">' + tr("ID") + '</td>\
|
||||
<td class="value_td">'+cluster.ID+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">' + tr("Name") + '</td>\
|
||||
<td class="value_td">'+cluster.NAME+'</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3>' + tr("Hosts") + '</h3>\
|
||||
<div class="panel_info">\
|
||||
<br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#hosts_tab" value="Host.create_dialog">'+tr("Create new host")+'</a><br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="show_tab_button" filter_id="'+cluster.ID+'" href="#hosts_tab">'+tr("Manage unclustered hosts")+'</a><br /></p>\
|
||||
\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</td>\
|
||||
<td style="width:50%">\
|
||||
<table style="width:100%">\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3>' + tr("Datastores") + '</h3>\
|
||||
<div class="panel_info">\
|
||||
<br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#datastores_tab" value="Datastore.create_dialog">'+tr("Create new datastore")+'</a><br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="show_tab_button" filter_id="'+cluster.ID+'" href="#datastores_tab">'+tr("Manage unclustered datastores")+'</a><br /></p>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td>\
|
||||
<div class="panel">\
|
||||
<h3>' + tr("Virtual Networks") + '</h3>\
|
||||
<div class="panel_info">\
|
||||
<br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#vnets_tab" value="Network.create_dialog">'+tr("Create new virtual network")+'</a><br />\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="show_tab_button" filter_id="'+cluster.ID+'" href="#vnets_tab">'+tr("Manage unclustered virtual networks")+'</a><br /></p>\
|
||||
</div>\
|
||||
</div>\
|
||||
</td>\
|
||||
</tr>\
|
||||
</table>\
|
||||
</td>\
|
||||
</tr></table>\
|
||||
';
|
||||
return html_code;
|
||||
};
|
||||
|
||||
//end cluster none special html
|
||||
|
||||
var html_code = '\
|
||||
<table class="dashboard_table">\
|
||||
@ -453,7 +528,7 @@ function removeClusterMenus(){
|
||||
// Sunstone.removeMainTab('cluster_vnets_tab_n',true);
|
||||
// Sunstone.removeMainTab('cluster_datastores_tab_n',true);
|
||||
// Sunstone.removeMainTab('cluster_hosts_tab_n',true);
|
||||
Sunstone.removeMainTab('cluster_tab_n',true);
|
||||
Sunstone.removeMainTab('cluster_tab_-',true);
|
||||
|
||||
for (var i=0; i < data.length; i++){
|
||||
var id = data[i][1];
|
||||
|
@ -207,7 +207,7 @@ var datastore_actions = {
|
||||
|
||||
"Datastore.delete" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Datastore.delete,
|
||||
call : OpenNebula.Datastore.del,
|
||||
callback : deleteDatastoreElement,
|
||||
elements: datastoreElements,
|
||||
error : onError,
|
||||
@ -271,7 +271,8 @@ var datastore_buttons = {
|
||||
"Datastore.update_dialog" : {
|
||||
type: "action",
|
||||
text: tr("Update properties"),
|
||||
alwaysActive: true
|
||||
alwaysActive: true,
|
||||
condition: mustBeAdmin,
|
||||
},
|
||||
"Datastore.addtocluster" : {
|
||||
type: "confirm_with_select",
|
||||
@ -296,7 +297,8 @@ var datastore_buttons = {
|
||||
},
|
||||
"Datastore.delete" : {
|
||||
type: "confirm",
|
||||
text: tr("Delete")
|
||||
text: tr("Delete"),
|
||||
condition: mustBeAdmin
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +445,7 @@ function updateDatastoreInfo(request,ds){
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Cluster")+'</td>\
|
||||
<td class="value_td">'+(element.CLUSTER.length ? element.CLUSTER : "-")+'</td>\
|
||||
<td class="value_td">'+(info.CLUSTER.length ? info.CLUSTER : "-")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("DS Mad")+'</td>\
|
||||
|
@ -97,7 +97,7 @@ var group_actions = {
|
||||
|
||||
"Group.delete" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Group.delete,
|
||||
call : OpenNebula.Group.del,
|
||||
callback : deleteGroupElement,
|
||||
error : onError,
|
||||
elements: groupElements,
|
||||
|
@ -189,7 +189,7 @@ var host_actions = {
|
||||
|
||||
"Host.delete" : {
|
||||
type: "multiple",
|
||||
call : OpenNebula.Host.delete,
|
||||
call : OpenNebula.Host.del,
|
||||
callback : deleteHostElement,
|
||||
elements: hostElements,
|
||||
error : onError,
|
||||
@ -271,30 +271,36 @@ var host_buttons = {
|
||||
},
|
||||
"Host.create_dialog" : {
|
||||
type: "create_dialog",
|
||||
text: tr("+ New")
|
||||
text: tr("+ New"),
|
||||
condition: mustBeAdmin
|
||||
},
|
||||
"Host.update_dialog" : {
|
||||
type: "action",
|
||||
text: tr("Update a template"),
|
||||
alwaysActive: true
|
||||
alwaysActive: true,
|
||||
condition: mustBeAdmin
|
||||
},
|
||||
"Host.addtocluster" : {
|
||||
type: "confirm_with_select",
|
||||
text: tr("Select cluster"),
|
||||
select: clusters_sel,
|
||||
tip: tr("Select the destination cluster:"),
|
||||
condition: mustBeAdmin
|
||||
},
|
||||
"Host.enable" : {
|
||||
type: "action",
|
||||
text: tr("Enable")
|
||||
text: tr("Enable"),
|
||||
condition: mustBeAdmin
|
||||
},
|
||||
"Host.disable" : {
|
||||
type: "action",
|
||||
text: tr("Disable")
|
||||
text: tr("Disable"),
|
||||
condition: mustBeAdmin
|
||||
},
|
||||
"Host.delete" : {
|
||||
type: "confirm",
|
||||
text: tr("Delete host")
|
||||
text: tr("Delete host"),
|
||||
condition: mustBeAdmin
|
||||
}
|
||||
};
|
||||
|
||||
@ -475,7 +481,7 @@ function updateHostInfo(request,host){
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">' + tr("Cluster") + '</td>\
|
||||
<td class="value_td">'+(host.CLUSTER.length ? host.CLUSTER : "-")+'</td>\
|
||||
<td class="value_td">'+(host_info.CLUSTER.length ? host_info.CLUSTER : "-")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">' + tr("State") + '</td>\
|
||||
@ -493,10 +499,6 @@ function updateHostInfo(request,host){
|
||||
<td class="key_td">'+ tr("VN MAD") +'</td>\
|
||||
<td class="value_td">'+host_info.VN_MAD+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+ tr("TM MAD") +'</td>\
|
||||
<td class="value_td">'+host_info.TM_MAD+'</td>\
|
||||
</tr>\
|
||||
</tbody>\
|
||||
</table>\
|
||||
<table id="host_shares_table" class="info_table">\
|
||||
|
@ -374,7 +374,7 @@ var image_actions = {
|
||||
|
||||
"Image.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Image.delete,
|
||||
call: OpenNebula.Image.del,
|
||||
callback: deleteImageElement,
|
||||
elements: imageElements,
|
||||
error: onError,
|
||||
|
@ -15,7 +15,7 @@
|
||||
/* -------------------------------------------------------------------------- */
|
||||
|
||||
var infra_tab_content =
|
||||
'<table class="dashboard_table" style=>\
|
||||
'<table class="dashboard_table" id="infra_dashboard" style=>\
|
||||
<tr>\
|
||||
<td style="width:50%">\
|
||||
<table style="width:100%">\
|
||||
@ -26,7 +26,7 @@ var infra_tab_content =
|
||||
<div class="panel_info">\
|
||||
\
|
||||
<table class="info_table">\
|
||||
<tr>\
|
||||
<tr class="cluster_related">\
|
||||
<td class="key_td">' + tr("Clusters") + '</td>\
|
||||
<td class="value_td"><span id="infra_total_clusters"></span></td>\
|
||||
</tr>\
|
||||
@ -54,7 +54,7 @@ var infra_tab_content =
|
||||
<h3>' + tr("Quickstart") + '</h3>\
|
||||
<div class="panel_info dashboard_p">\
|
||||
<p></br>\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#clusters_tab" value="Cluster.create_dialog">'+tr("Create new Cluster")+'</a></br>\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon cluster_related" /><a class="action_button cluster_related" href="#clusters_tab" value="Cluster.create_dialog">'+tr("Create new Cluster")+'</a></br>\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#hosts_tab" value="Host.create_dialog">'+tr("Create new Host")+'</a></br>\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#datastores_tab" value="Datastore.create_dialog">'+tr("Create new Datastore")+'</a></br>\
|
||||
<span class="ui-icon ui-icon-arrowreturnthick-1-e inline-icon" /><a class="action_button" href="#vnets_tab" value="Network.create_dialog">'+tr("Create new Virtual Network")+'</a></br>\
|
||||
@ -72,7 +72,7 @@ var infra_tab_content =
|
||||
<div class="panel">\
|
||||
<h3>' + tr("Infrastructure resources") + '</h3>\
|
||||
<div class="panel_info">\
|
||||
<p>'+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks and the Clusters they are placed in. The Clusters node can be expanded, and resources can be managed for each cluster.")+'</p>\
|
||||
<p>'+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks. Users in the oneadmin group can manage clusters as well.")+'</p>\
|
||||
<p>'+tr("You can find further information on the following links:")+'</p>\
|
||||
<ul>\
|
||||
<li><a href="http://opennebula.org/documentation:rel3.4:hostsubsystem" target="_blank">Host subsystem</a></li>\
|
||||
@ -117,5 +117,6 @@ function updateInfraDashboard(what,json_info){
|
||||
};
|
||||
|
||||
$(document).ready(function(){
|
||||
|
||||
if (!mustBeAdmin())
|
||||
$('table#infra_dashboard .cluster_related', main_tabs_context).hide();
|
||||
});
|
@ -186,7 +186,7 @@ var create_template_tmpl = '<div id="template_create_tabs">\
|
||||
<h3>'+tr("Add disks/images")+' <a id="add_disks" class="icon_left" href="#"><span class="ui-icon ui-icon-plus" /></a></h3>\
|
||||
</div>\
|
||||
<fieldset><legend>'+tr("Disks")+'</legend>\
|
||||
<div class="" id="image_vs_disk">\
|
||||
<div class="" id="image_vs_disk" style="display:none;">\
|
||||
<label>'+tr("Add disk/image")+'</label>\
|
||||
<input type="radio" id="add_disk" name="image_vs_disk" value="disk">'+tr("Disk")+'</input>\
|
||||
<!--<label for="add_disk">Add a disk</label>-->\
|
||||
@ -228,6 +228,11 @@ var create_template_tmpl = '<div id="template_create_tabs">\
|
||||
<input type="text" id="SOURCE" name="source" />\
|
||||
<div class="tip">'+tr("Disk file location path or URL")+'</div>\
|
||||
</div>\
|
||||
<div class="vm_param kvm xen vmware add_disk">\
|
||||
<label for="TM_MAD">'+tr("Transfer Manager")+':</label>\
|
||||
<input type="text" id="TM_MAD" name="tm_mad" />\
|
||||
<div class="tip">'+tr("shared,ssh,iscsi,dummy")+'</div>\
|
||||
</div>\
|
||||
<div class="vm_param kvm_opt xen_opt add_disk ">\
|
||||
<!--Mandatory for swap, fs and block images-->\
|
||||
<label for="SIZE">'+tr("Size")+':</label>\
|
||||
@ -283,7 +288,7 @@ var create_template_tmpl = '<div id="template_create_tabs">\
|
||||
<h3>'+tr("Setup Networks")+' <a id="add_networks" class="icon_left" href="#"><span class="ui-icon ui-icon-plus" /></a></h3>\
|
||||
</div>\
|
||||
<fieldset><legend>'+tr("Network")+'</legend>\
|
||||
<div class="" id="network_vs_niccfg">\
|
||||
<div class="" id="network_vs_niccfg" style="display:none;">\
|
||||
<label>'+tr("Add network")+'</label>\
|
||||
<input type="radio" id="add_network" name="network_vs_niccfg" value="network">'+tr("Predefined")+'</input>\
|
||||
<!--<label style="width:200px;" for="add_network">Pre-defined network</label>-->\
|
||||
@ -324,7 +329,7 @@ var create_template_tmpl = '<div id="template_create_tabs">\
|
||||
<input type="text" id="SCRIPT" name="script" />\
|
||||
<div class="tip">'+tr("Name of a shell script to be executed after creating the tun device for the VM")+'</div>\
|
||||
</div>\
|
||||
<div class="vm_param kvm_opt xen_opt vmware_opt niccfg">\
|
||||
<div class="vm_param kvm_opt xen_opt vmware_opt niccfg network">\
|
||||
<label for="MODEL">'+tr("Model")+':</label>\
|
||||
<input type="text" id="MODEL" name="model" />\
|
||||
<div class="tip">'+tr("Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.")+'</div>\
|
||||
@ -720,7 +725,7 @@ var template_actions = {
|
||||
|
||||
"Template.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Template.delete,
|
||||
call: OpenNebula.Template.del,
|
||||
callback: deleteTemplateElement,
|
||||
elements: templateElements,
|
||||
error: onError,
|
||||
@ -1406,7 +1411,7 @@ function setupCreateTemplateDialog(){
|
||||
$('#image_vs_disk input',section_disks).click(function(){
|
||||
//$('fieldset',section_disks).show();
|
||||
$('.vm_param', section_disks).show();
|
||||
var select = $('#image_vs_disk :checked',section_disks).val();
|
||||
var select = $(this).val();
|
||||
switch (select)
|
||||
{
|
||||
case "disk":
|
||||
@ -1540,7 +1545,11 @@ function setupCreateTemplateDialog(){
|
||||
box_remove_element(section_disks,'#disks_box');
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
//preselect now hidden option
|
||||
$('#image_vs_disk input#add_image',section_disks).trigger('click');
|
||||
|
||||
};
|
||||
|
||||
// Sets up the network section
|
||||
var networks_setup = function(){
|
||||
@ -1570,7 +1579,7 @@ function setupCreateTemplateDialog(){
|
||||
$('.firewall_select',section_networks).show();
|
||||
$('.firewall_select select option',section_networks).removeAttr('selected');
|
||||
|
||||
select = $('#network_vs_niccfg :checked',section_networks).val();
|
||||
select = $(this).val();
|
||||
switch (select) {
|
||||
case "network":
|
||||
$('.niccfg',section_networks).hide();
|
||||
@ -1648,6 +1657,8 @@ function setupCreateTemplateDialog(){
|
||||
return false;
|
||||
});
|
||||
|
||||
//preselect now hidden option
|
||||
$('#network_vs_niccfg input#add_network',section_networks).trigger('click');
|
||||
};
|
||||
|
||||
//Sets up the input section - basicly enabling adding and removing from box
|
||||
|
@ -197,7 +197,7 @@ var user_actions = {
|
||||
|
||||
"User.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.User.delete,
|
||||
call: OpenNebula.User.del,
|
||||
callback: deleteUserElement,
|
||||
elements: userElements,
|
||||
error: onError,
|
||||
|
@ -63,6 +63,7 @@ var vms_tab_content =
|
||||
<th>'+tr("CPU")+'</th>\
|
||||
<th>'+tr("Memory")+'</th>\
|
||||
<th>'+tr("Hostname")+'</th>\
|
||||
<th>'+tr("IPs")+'</th>\
|
||||
<th>'+tr("Start Time")+'</th>\
|
||||
<th>'+tr("VNC Access")+'</th>\
|
||||
</tr>\
|
||||
@ -353,7 +354,7 @@ var vm_actions = {
|
||||
|
||||
"VM.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.VM.delete,
|
||||
call: OpenNebula.VM.del,
|
||||
callback: deleteVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
@ -592,6 +593,10 @@ var vm_info_panel = {
|
||||
"vm_log_tab" : {
|
||||
title: tr("VM log"),
|
||||
content: ""
|
||||
},
|
||||
"vm_history_tab" : {
|
||||
title: tr("History information"),
|
||||
content: "",
|
||||
}
|
||||
}
|
||||
|
||||
@ -619,7 +624,21 @@ function vmShow(req) {
|
||||
// Returns a human readable running time for a VM
|
||||
function str_start_time(vm){
|
||||
return pretty_time(vm.STIME);
|
||||
}
|
||||
};
|
||||
|
||||
function ip_str(vm){
|
||||
var nic = vm.TEMPLATE.NIC;
|
||||
var ip = '--';
|
||||
if ($.isArray(nic)) {
|
||||
ip = '';
|
||||
$.each(nic, function(index,value){
|
||||
ip += value.IP+'<br />';
|
||||
});
|
||||
} else if (nic && nic.IP) {
|
||||
ip = nic.IP;
|
||||
};
|
||||
return ip;
|
||||
};
|
||||
|
||||
// Returns an array formed by the information contained in the vm_json
|
||||
// and ready to be introduced in a dataTable
|
||||
@ -650,10 +669,11 @@ function vMachineElementArray(vm_json){
|
||||
vm.CPU,
|
||||
humanize_size(vm.MEMORY),
|
||||
hostname,
|
||||
ip_str(vm),
|
||||
str_start_time(vm),
|
||||
vncIcon(vm)
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//Creates a listener for the TDs of the VM table
|
||||
@ -703,7 +723,69 @@ function updateVMachinesView(request, vmachine_list){
|
||||
updateView(vmachine_list_array,dataTable_vMachines);
|
||||
updateDashboard("vms",vmachine_list);
|
||||
updateVResDashboard("vms",vmachine_list);
|
||||
}
|
||||
};
|
||||
|
||||
function generateHistoryTable(vm){
|
||||
var html = ' <table id="vm_history_table" class="info_table" style="width:80%">\
|
||||
<thead>\
|
||||
<tr>\
|
||||
<th>'+tr("Sequence")+'</th>\
|
||||
<th>'+tr("Hostname")+'</th>\
|
||||
<th>'+tr("Reason")+'</th>\
|
||||
<th>'+tr("State change time")+'</th>\
|
||||
<th>'+tr("Total time")+'</th>\
|
||||
<th colspan="2">'+tr("Prolog time")+'</th>\
|
||||
</tr>\
|
||||
</thead>\
|
||||
<tbody>';
|
||||
|
||||
var history = [];
|
||||
|
||||
if ($.isArray(vm.HISTORY_RECORDS.HISTORY))
|
||||
history = vm.HISTORY_RECORDS.HISTORY;
|
||||
else if (vm.HISTORY_RECORDS.HISTORY.SEQ)
|
||||
history = [vm.HISTORY_RECORDS.HISTORY];
|
||||
|
||||
var now = Math.round(new Date().getTime() / 1000);
|
||||
|
||||
for (var i=0; i < history.length; i++){
|
||||
// :TIME time calculations copied from onevm_helper.rb
|
||||
var stime = parseInt(history[i].STIME, 10);
|
||||
|
||||
var etime = parseInt(history[i].ETIME, 10)
|
||||
etime = etime == 0 ? now : etime;
|
||||
|
||||
var dtime = etime - stime;
|
||||
// end :TIME
|
||||
|
||||
//:PTIME
|
||||
var stime2 = parseInt(history[i].PSTIME, 10);
|
||||
var etime2;
|
||||
var ptime2 = parseInt(history[i].PETIME, 10);
|
||||
if (stime2 == 0)
|
||||
etime2 = 0;
|
||||
else
|
||||
etime2 = ptime2 == 0 ? now : ptime2;
|
||||
var dtime2 = etime2 - stime2;
|
||||
|
||||
//end :PTIME
|
||||
|
||||
|
||||
html += ' <tr>\
|
||||
<td style="width:20%">'+history[i].SEQ+'</td>\
|
||||
<td style="width:20%">'+history[i].HOSTNAME+'</td>\
|
||||
<td style="width:16%">'+OpenNebula.Helper.resource_state("VM_MIGRATE_REASON",parseInt(history[i].REASON, 10))+'</td>\
|
||||
<td style="width:16%">'+pretty_time(history[i].STIME)+'</td>\
|
||||
<td style="width:16%">'+pretty_time_runtime(dtime)+'</td>\
|
||||
<td style="width:16%">'+pretty_time_runtime(dtime2)+'</td>\
|
||||
<td></td>\
|
||||
</tr>'
|
||||
};
|
||||
html += '</tbody>\
|
||||
</table>';
|
||||
return html;
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Refreshes the information panel for a VM
|
||||
@ -805,7 +887,7 @@ function updateVMInfo(request,vm){
|
||||
</tr>\
|
||||
</tbody>\
|
||||
</table>'
|
||||
}
|
||||
};
|
||||
|
||||
var template_tab = {
|
||||
title: tr("VM Template"),
|
||||
@ -814,21 +896,27 @@ function updateVMInfo(request,vm){
|
||||
<thead><tr><th colspan="2">'+tr("VM template")+'</th></tr></thead>'+
|
||||
prettyPrintJSON(vm_info.TEMPLATE)+
|
||||
'</table>'
|
||||
}
|
||||
};
|
||||
|
||||
var log_tab = {
|
||||
title: tr("VM log"),
|
||||
content: '<div>'+spinner+'</div>'
|
||||
}
|
||||
};
|
||||
|
||||
var monitoring_tab = {
|
||||
title: tr("Monitoring information"),
|
||||
content: generateMonitoringDivs(vm_graphs,"vm_monitor_")
|
||||
}
|
||||
};
|
||||
|
||||
var history_tab = {
|
||||
title: tr("History information"),
|
||||
content: generateHistoryTable(vm_info),
|
||||
};
|
||||
|
||||
Sunstone.updateInfoPanelTab("vm_info_panel","vm_info_tab",info_tab);
|
||||
Sunstone.updateInfoPanelTab("vm_info_panel","vm_template_tab",template_tab);
|
||||
Sunstone.updateInfoPanelTab("vm_info_panel","vm_log_tab",log_tab);
|
||||
Sunstone.updateInfoPanelTab("vm_info_panel","vm_history_tab",history_tab);
|
||||
Sunstone.updateInfoPanelTab("vm_info_panel","vm_monitoring_tab",monitoring_tab);
|
||||
|
||||
//Pop up the info panel and asynchronously get vm_log and stats
|
||||
@ -1284,9 +1372,9 @@ $(document).ready(function(){
|
||||
"aoColumnDefs": [
|
||||
{ "bSortable": false, "aTargets": ["check"] },
|
||||
{ "sWidth": "60px", "aTargets": [0,6,7] },
|
||||
{ "sWidth": "35px", "aTargets": [1,10] },
|
||||
{ "sWidth": "150px", "aTargets": [5,9] },
|
||||
{ "sWidth": "100px", "aTargets": [2,3] }
|
||||
{ "sWidth": "35px", "aTargets": [1,11] },
|
||||
{ "sWidth": "150px", "aTargets": [5,10] },
|
||||
{ "sWidth": "100px", "aTargets": [2,3,9] }
|
||||
],
|
||||
"oLanguage": (datatable_lang != "") ?
|
||||
{
|
||||
@ -1297,7 +1385,7 @@ $(document).ready(function(){
|
||||
dataTable_vMachines.fnClearTable();
|
||||
addElement([
|
||||
spinner,
|
||||
'','','','','','','','','',''],dataTable_vMachines);
|
||||
'','','','','','','','','','',''],dataTable_vMachines);
|
||||
Sunstone.runAction("VM.list");
|
||||
|
||||
setupCreateVMDialog();
|
||||
|
@ -283,7 +283,7 @@ var vnet_actions = {
|
||||
|
||||
"Network.delete" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.Network.delete,
|
||||
call: OpenNebula.Network.del,
|
||||
callback: deleteVNetworkElement,
|
||||
elements: vnElements,
|
||||
error: onError,
|
||||
@ -566,7 +566,7 @@ function updateVNetworkInfo(request,vn){
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Cluster")+'</td>\
|
||||
<td class="value_td">'+(network.CLUSTER.length ? network.CLUSTER : "-")+'</td>\
|
||||
<td class="value_td">'+(vn_info.CLUSTER.length ? vn_info.CLUSTER : "-")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">'+tr("Owner")+'</td>\
|
||||
|
@ -60,6 +60,20 @@ function pretty_time_axis(time){
|
||||
return hour + ":" + mins + ":" + secs;// + " " + month + "/" + day;
|
||||
}
|
||||
|
||||
function pretty_time_runtime(time){
|
||||
var d = new Date();
|
||||
d.setTime(time*1000);
|
||||
|
||||
var secs = pad(d.getUTCSeconds(),2);
|
||||
var hour = pad(d.getUTCHours(),2);
|
||||
var mins = pad(d.getUTCMinutes(),2);
|
||||
var day = d.getUTCDate()-1;
|
||||
var month = pad(d.getUTCMonth()+1,2); //getMonths returns 0-11
|
||||
var year = d.getUTCFullYear();
|
||||
|
||||
return day + "d " + hour + ":" + mins;// + ":" + secs;// + " " + month + "/" + day;
|
||||
}
|
||||
|
||||
//returns a human readable size in Kilo, Mega, Giga or Tera bytes
|
||||
function humanize_size(value) {
|
||||
if (typeof(value) === "undefined") {
|
||||
|
@ -465,7 +465,19 @@ function insertTab(tab_name){
|
||||
|
||||
$('div#'+tab_name,main_tabs_context).html(tab_info.content);
|
||||
|
||||
$('div#menu ul#navigation').append('<li id="li_'+tab_name+'" class="'+tabClass+' '+parent+'">'+tab_info.title+'<span class="ui-icon ui-icon-circle-plus plusIcon"></span></li>');
|
||||
var li_item = '<li id="li_'+tab_name+'" class="'+tabClass+' '+parent+'">'+tab_info.title+'<span class="ui-icon ui-icon-circle-plus plusIcon"></span></li>';
|
||||
|
||||
//if this is a submenu...
|
||||
if (parent.length) {
|
||||
var children = $('div#menu ul#navigation li.'+parent);
|
||||
//if there are other submenus, insert after last of them
|
||||
if (children.length)
|
||||
$(children[children.length-1]).after(li_item);
|
||||
else //instert after parent menu
|
||||
$('div#menu ul#navigation li#li_'+parent).after(li_item);
|
||||
} else { //not a submenu, instert in the end
|
||||
$('div#menu ul#navigation').append(li_item);
|
||||
};
|
||||
|
||||
if (parent){ //this is a subtab
|
||||
$('div#menu li#li_'+tab_name).hide();//hide by default
|
||||
|
Loading…
x
Reference in New Issue
Block a user