mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-20 10:50:08 +03:00
Merge branch 'master' into feature-1112
This commit is contained in:
commit
e9e84d35f3
@ -1095,8 +1095,7 @@ ETC_CLIENT_FILES="src/cli/etc/group.default"
|
||||
# Sunstone files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
SUNSTONE_FILES="src/sunstone/config.ru \
|
||||
src/sunstone/sunstone-server.rb \
|
||||
SUNSTONE_FILES="src/sunstone/sunstone-server.rb \
|
||||
src/sunstone/OpenNebulaVNC.rb"
|
||||
|
||||
SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server"
|
||||
@ -1241,8 +1240,7 @@ src/sunstone/public/locale/ru/ru_datatable.txt"
|
||||
# Ozones files
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
OZONES_FILES="src/ozones/Server/config.ru \
|
||||
src/ozones/Server/ozones-server.rb"
|
||||
OZONES_FILES="src/ozones/Server/ozones-server.rb"
|
||||
|
||||
OZONES_BIN_FILES="src/ozones/Server/bin/ozones-server"
|
||||
|
||||
@ -1448,6 +1446,9 @@ if [ "$UNINSTALL" = "no" ] ; then
|
||||
for d in $MAKE_DIRS; do
|
||||
mkdir -p $DESTDIR$d
|
||||
done
|
||||
|
||||
# Remove old migrators
|
||||
rm $LIB_LOCATION/ruby/onedb/*.rb
|
||||
fi
|
||||
|
||||
# --- Install/Uninstall files ---
|
||||
|
@ -39,11 +39,12 @@ class CloudAuth
|
||||
# Tokens will be generated if time > EXPIRE_TIME - EXPIRE_MARGIN
|
||||
EXPIRE_MARGIN = 300
|
||||
|
||||
attr_reader :client, :token
|
||||
attr_reader :client, :token, :logger
|
||||
|
||||
# conf a hash with the configuration attributes as symbols
|
||||
def initialize(conf)
|
||||
def initialize(conf, logger=nil)
|
||||
@conf = conf
|
||||
@logger = logger
|
||||
|
||||
@token_expiration_time = Time.now.to_i + EXPIRE_DELTA
|
||||
|
||||
|
@ -37,7 +37,7 @@ class CloudServer
|
||||
##########################################################################
|
||||
# Public attributes
|
||||
##########################################################################
|
||||
attr_reader :config
|
||||
attr_reader :config, :logger
|
||||
|
||||
# Initializes the Cloud server based on a config file
|
||||
# config_file:: _String_ for the server. MUST include the following
|
||||
@ -45,9 +45,10 @@ class CloudServer
|
||||
# AUTH
|
||||
# VM_TYPE
|
||||
# XMLRPC
|
||||
def initialize(config)
|
||||
def initialize(config, logger=nil)
|
||||
# --- Load the Cloud Server configuration file ---
|
||||
@config = config
|
||||
@logger = logger
|
||||
end
|
||||
#
|
||||
# Prints the configuration of the server
|
||||
@ -82,3 +83,54 @@ class CloudServer
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
module CloudLogger
|
||||
require 'logger'
|
||||
|
||||
DEBUG_LEVEL = [
|
||||
Logger::ERROR, # 0
|
||||
Logger::WARN, # 1
|
||||
Logger::INFO, # 2
|
||||
Logger::DEBUG # 3
|
||||
]
|
||||
|
||||
# Mon Feb 27 06:02:30 2012 [Clo] [E]: Error message example
|
||||
MSG_FORMAT = %{%s [%s]: %s\n}
|
||||
|
||||
# Mon Feb 27 06:02:30 2012
|
||||
DATE_FORMAT = "%a %b %d %H:%M:%S %Y"
|
||||
|
||||
# Patch logger class to be compatible with Rack::CommonLogger
|
||||
class ::Logger
|
||||
def write(msg)
|
||||
info msg.chop
|
||||
end
|
||||
end
|
||||
|
||||
def enable_logging(path=nil, debug_level=3)
|
||||
path ||= $stdout
|
||||
logger = ::Logger.new(path)
|
||||
logger.level = DEBUG_LEVEL[debug_level]
|
||||
logger.formatter = proc do |severity, datetime, progname, msg|
|
||||
MSG_FORMAT % [
|
||||
datetime.strftime(DATE_FORMAT),
|
||||
severity[0..0],
|
||||
msg ]
|
||||
end
|
||||
|
||||
# Add the logger instance to the Sinatra settings
|
||||
set :logger, logger
|
||||
|
||||
# The logging will be configured in Rack, not in Sinatra
|
||||
disable :logging
|
||||
|
||||
# Use the logger instance in the Rack methods
|
||||
use Rack::CommonLogger, logger
|
||||
|
||||
helpers do
|
||||
def logger
|
||||
settings.logger
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -34,6 +34,9 @@
|
||||
# x509, for x509 certificate encryption of tokens
|
||||
:core_auth: cipher
|
||||
|
||||
# 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
:debug_level: 3
|
||||
|
||||
# VM types allowed and its template file (inside templates directory)
|
||||
:instance_types:
|
||||
:m1.small:
|
||||
|
@ -61,8 +61,8 @@ class EC2QueryServer < CloudServer
|
||||
|
||||
###########################################################################
|
||||
|
||||
def initialize(client, config)
|
||||
super(config)
|
||||
def initialize(client, config, logger)
|
||||
super(config, logger)
|
||||
|
||||
@client = client
|
||||
end
|
||||
|
@ -20,19 +20,23 @@
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
|
||||
LOG_LOCATION = "/var/log/one"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
CONFIGURATION_FILE = "/etc/one/econe.conf"
|
||||
TEMPLATE_LOCATION = "/etc/one/ec2query_templates"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
|
||||
VAR_LOCATION = ONE_LOCATION+"/var"
|
||||
CONFIGURATION_FILE = ONE_LOCATION+"/etc/econe.conf"
|
||||
TEMPLATE_LOCATION = ONE_LOCATION+"/etc/ec2query_templates"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
LOG_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
VIEWS_LOCATION = RUBY_LIB_LOCATION + "/cloud/econe/views"
|
||||
EC2_AUTH = VAR_LOCATION + "/.one/ec2_auth"
|
||||
EC2_AUTH = VAR_LOCATION + "/.one/ec2_auth"
|
||||
EC2_LOG = LOG_LOCATION + "/econe-server.log"
|
||||
CONFIGURATION_FILE = ETC_LOCATION + "/occi-server.conf"
|
||||
|
||||
TEMPLATE_LOCATION = ETC_LOCATION + "/occi_templates"
|
||||
VIEWS_LOCATION = RUBY_LIB_LOCATION + "/cloud/econe/views"
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cloud"
|
||||
@ -57,12 +61,13 @@ include OpenNebula
|
||||
begin
|
||||
conf = YAML.load_file(CONFIGURATION_FILE)
|
||||
rescue Exception => e
|
||||
puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
STDERR.puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
conf[:template_location] = TEMPLATE_LOCATION
|
||||
conf[:views] = VIEWS_LOCATION
|
||||
conf[:debug_level] ||= 3
|
||||
|
||||
CloudServer.print_configuration(conf)
|
||||
|
||||
@ -70,21 +75,28 @@ CloudServer.print_configuration(conf)
|
||||
# Sinatra Configuration
|
||||
##############################################################################
|
||||
set :config, conf
|
||||
set :bind, settings.config[:server]
|
||||
set :port, settings.config[:port]
|
||||
|
||||
include CloudLogger
|
||||
enable_logging EC2_LOG, settings.config[:debug_level].to_i
|
||||
|
||||
if CloudServer.is_port_open?(settings.config[:server],
|
||||
settings.config[:port])
|
||||
puts "Port busy, please shutdown the service or move econe server port."
|
||||
exit 1
|
||||
settings.logger.error {
|
||||
"Port #{settings.config[:port]} busy, please shutdown " <<
|
||||
"the service or move occi server port."
|
||||
}
|
||||
exit -1
|
||||
end
|
||||
|
||||
set :bind, settings.config[:server]
|
||||
set :port, settings.config[:port]
|
||||
|
||||
begin
|
||||
ENV["ONE_CIPHER_AUTH"] = EC2_AUTH
|
||||
cloud_auth = CloudAuth.new(settings.config)
|
||||
cloud_auth = CloudAuth.new(settings.config, settings.logger)
|
||||
rescue => e
|
||||
puts "Error initializing authentication system"
|
||||
puts e.message
|
||||
settings.logger.error {"Error initializing authentication system"}
|
||||
settings.logger.error {e.message}
|
||||
exit -1
|
||||
end
|
||||
|
||||
@ -116,6 +128,7 @@ before do
|
||||
params['econe_path'] = settings.econe_path
|
||||
username = settings.cloud_auth.auth(request.env, params)
|
||||
rescue Exception => e
|
||||
logger.error {e.message}
|
||||
error 500, error_xml("AuthFailure", 0)
|
||||
end
|
||||
|
||||
@ -123,7 +136,7 @@ before do
|
||||
error 401, error_xml("AuthFailure", 0)
|
||||
else
|
||||
client = settings.cloud_auth.client(username)
|
||||
@econe_server = EC2QueryServer.new(client, settings.config)
|
||||
@econe_server = EC2QueryServer.new(client, settings.config, settings.logger)
|
||||
end
|
||||
end
|
||||
|
||||
@ -179,6 +192,7 @@ def do_http_request(params)
|
||||
end
|
||||
|
||||
if OpenNebula::is_error?(result)
|
||||
logger.error(result.message)
|
||||
error rc, error_xml(result.message, 0)
|
||||
end
|
||||
|
||||
|
@ -34,8 +34,8 @@
|
||||
# x509, for x509 certificate encryption of tokens
|
||||
:core_auth: cipher
|
||||
|
||||
# Life-time in seconds for token renewal (that used to handle OpenNebula auths)
|
||||
:token_expiration_delta: 1800
|
||||
# 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
:debug_level: 3
|
||||
|
||||
# VM types allowed and its template file (inside templates directory)
|
||||
:instance_types:
|
||||
|
@ -52,8 +52,8 @@ class OCCIServer < CloudServer
|
||||
# Server initializer
|
||||
# config_file:: _String_ path of the config file
|
||||
# template:: _String_ path to the location of the templates
|
||||
def initialize(client, config)
|
||||
super(config)
|
||||
def initialize(client, config, logger)
|
||||
super(config, logger)
|
||||
|
||||
if config[:ssl_server]
|
||||
@base_url=config[:ssl_server]
|
||||
@ -81,10 +81,10 @@ class OCCIServer < CloudServer
|
||||
############################################################################
|
||||
|
||||
def get_collections(request)
|
||||
xml_resp = "<COLLECTIONS>\n"
|
||||
xml_resp = "<COLLECTIONS>"
|
||||
|
||||
COLLECTIONS.each { |c|
|
||||
xml_resp << "\t<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\">\n"
|
||||
COLLECTIONS.sort.each { |c|
|
||||
xml_resp << "<#{c.upcase}_COLLECTION href=\"#{@base_url}/#{c}\"/>"
|
||||
}
|
||||
|
||||
xml_resp << "</COLLECTIONS>"
|
||||
@ -97,7 +97,7 @@ class OCCIServer < CloudServer
|
||||
<INSTANCE_TYPE href="<%= @base_url %>/instance_type/<%=name%>" name="<%= name %>">
|
||||
<ID><%= name.to_s %></ID>
|
||||
<NAME><%= name.to_s %></NAME>
|
||||
<% opts.each { |elem, value|
|
||||
<% opts.sort{|k1,k2| k1[0].to_s<=>k2[0].to_s}.each { |elem, value|
|
||||
next if elem==:template
|
||||
str = elem.to_s.upcase %>
|
||||
<<%= str %>><%= value %></<%= str %>>
|
||||
@ -106,9 +106,11 @@ class OCCIServer < CloudServer
|
||||
}
|
||||
|
||||
def get_instance_types(request)
|
||||
xml_resp = "<INSTANCE_TYPE_COLLECTION>\n"
|
||||
xml_resp = "<INSTANCE_TYPE_COLLECTION>"
|
||||
|
||||
@config[:instance_types].each { |name, opts|
|
||||
@config[:instance_types].sort { |k1,k2|
|
||||
k1[0].to_s<=>k2[0].to_s
|
||||
}.each { |name, opts|
|
||||
if request.params['verbose']
|
||||
begin
|
||||
occi_it = ERB.new(INSTANCE_TYPE)
|
||||
@ -120,7 +122,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
xml_resp << occi_it.gsub(/\n\s*/,'')
|
||||
else
|
||||
xml_resp << "\t<INSTANCE_TYPE href=\"#{@base_url}/instance_type/#{name.to_s}\" name=\"#{name}\">\n"
|
||||
xml_resp << "<INSTANCE_TYPE href=\"#{@base_url}/instance_type/#{name.to_s}\" name=\"#{name}\"/>"
|
||||
end
|
||||
}
|
||||
|
||||
@ -163,7 +165,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(vmpool, :status=>200, :verbose=>request.params['verbose'])
|
||||
return to_occi_xml(vmpool, :code=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
|
||||
@ -183,7 +185,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(network_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
return to_occi_xml(network_pool, :code=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
# Gets the pool representation of STORAGES
|
||||
@ -202,7 +204,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(image_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
return to_occi_xml(image_pool, :code=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
# Gets the pool representation of USERs
|
||||
@ -219,7 +221,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(user_pool, :status=>200, :verbose=>request.params['verbose'])
|
||||
return to_occi_xml(user_pool, :code=>200, :verbose=>request.params['verbose'])
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -255,7 +257,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
vm.info
|
||||
return to_occi_xml(vm, :status=>201)
|
||||
return to_occi_xml(vm, :code=>201)
|
||||
end
|
||||
|
||||
# Get the representation of a COMPUTE resource
|
||||
@ -274,7 +276,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(vm, :status=>200)
|
||||
return to_occi_xml(vm, :code=>200)
|
||||
end
|
||||
|
||||
# Deletes a COMPUTE resource
|
||||
@ -317,7 +319,7 @@ class OCCIServer < CloudServer
|
||||
return result, code
|
||||
else
|
||||
vm.info
|
||||
return to_occi_xml(vm, :status=>code)
|
||||
return to_occi_xml(vm, :code=>code)
|
||||
end
|
||||
end
|
||||
|
||||
@ -347,7 +349,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
network.info
|
||||
return to_occi_xml(network, :status=>201)
|
||||
return to_occi_xml(network, :code=>201)
|
||||
end
|
||||
|
||||
# Retrieves a NETWORK resource
|
||||
@ -365,7 +367,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(network, :status=>200)
|
||||
return to_occi_xml(network, :code=>200)
|
||||
end
|
||||
|
||||
# Deletes a NETWORK resource
|
||||
@ -411,7 +413,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
vnet.info
|
||||
return to_occi_xml(vnet, :status=>202)
|
||||
return to_occi_xml(vnet, :code=>202)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -457,7 +459,7 @@ class OCCIServer < CloudServer
|
||||
end
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
return to_occi_xml(image, :status=>201)
|
||||
return to_occi_xml(image, :code=>201)
|
||||
end
|
||||
|
||||
# Get a STORAGE resource
|
||||
@ -476,7 +478,7 @@ class OCCIServer < CloudServer
|
||||
end
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
return to_occi_xml(image, :status=>200)
|
||||
return to_occi_xml(image, :code=>200)
|
||||
end
|
||||
|
||||
# Deletes a STORAGE resource (Not yet implemented)
|
||||
@ -530,7 +532,7 @@ class OCCIServer < CloudServer
|
||||
|
||||
# --- Prepare XML Response ---
|
||||
image.info
|
||||
return to_occi_xml(image, :status=>202)
|
||||
return to_occi_xml(image, :code=>202)
|
||||
end
|
||||
|
||||
# Get the representation of a USER
|
||||
@ -549,7 +551,7 @@ class OCCIServer < CloudServer
|
||||
return rc, CloudServer::HTTP_ERROR_CODE[rc.errno]
|
||||
end
|
||||
|
||||
return to_occi_xml(user, :status=>200)
|
||||
return to_occi_xml(user, :code=>200)
|
||||
end
|
||||
|
||||
############################################################################
|
||||
@ -566,7 +568,7 @@ class OCCIServer < CloudServer
|
||||
return [404, error]
|
||||
end
|
||||
|
||||
vnc_proxy = OpenNebulaVNC.new(config,{:json_errors => false})
|
||||
vnc_proxy = OpenNebulaVNC.new(config, logger, {:json_errors => false})
|
||||
return vnc_proxy.start(vm)
|
||||
end
|
||||
|
||||
@ -574,7 +576,8 @@ class OCCIServer < CloudServer
|
||||
begin
|
||||
OpenNebulaVNC.stop(pipe)
|
||||
rescue Exception => e
|
||||
return [500, e.message]
|
||||
logger.error {e.message}
|
||||
return [500, "Error stopping VNC. Please check server logs."]
|
||||
end
|
||||
|
||||
return [200,nil]
|
||||
|
@ -25,18 +25,22 @@
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
LOG_LOCATION = "/var/log/one"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
TEMPLATE_LOCATION="/etc/one/occi_templates"
|
||||
CONFIGURATION_FILE = "/etc/one/occi-server.conf"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
VAR_LOCATION = ONE_LOCATION+"/var"
|
||||
TEMPLATE_LOCATION=ONE_LOCATION+"/etc/occi_templates"
|
||||
CONFIGURATION_FILE = ONE_LOCATION+"/etc/occi-server.conf"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
LOG_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
OCCI_AUTH = VAR_LOCATION + "/.one/occi_auth"
|
||||
OCCI_AUTH = VAR_LOCATION + "/.one/occi_auth"
|
||||
OCCI_LOG = LOG_LOCATION + "/occi-server.log"
|
||||
CONFIGURATION_FILE = ETC_LOCATION + "/occi-server.conf"
|
||||
|
||||
TEMPLATE_LOCATION = ETC_LOCATION + "/occi_templates"
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cloud/occi"
|
||||
@ -59,42 +63,55 @@ require 'CloudAuth'
|
||||
include OpenNebula
|
||||
|
||||
##############################################################################
|
||||
# Parse Configuration file
|
||||
# Configuration
|
||||
##############################################################################
|
||||
# Set Configuration settings
|
||||
begin
|
||||
conf = YAML.load_file(CONFIGURATION_FILE)
|
||||
rescue Exception => e
|
||||
puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
STDERR.puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
conf[:template_location] = TEMPLATE_LOCATION
|
||||
conf[:debug_level] ||= 3
|
||||
|
||||
CloudServer.print_configuration(conf)
|
||||
|
||||
##############################################################################
|
||||
# Sinatra Configuration
|
||||
##############################################################################
|
||||
set :config, conf
|
||||
|
||||
|
||||
# Enable Logger
|
||||
include CloudLogger
|
||||
enable_logging OCCI_LOG, settings.config[:debug_level].to_i
|
||||
|
||||
|
||||
# Set Sinatra configuration
|
||||
use Rack::Session::Pool, :key => 'occi'
|
||||
|
||||
set :public, Proc.new { File.join(root, "ui/public") }
|
||||
set :views, settings.root + '/ui/views'
|
||||
set :config, conf
|
||||
|
||||
if CloudServer.is_port_open?(settings.config[:server],
|
||||
settings.config[:port])
|
||||
puts "Port busy, please shutdown the service or move occi server port."
|
||||
exit
|
||||
settings.logger.error {
|
||||
"Port #{settings.config[:port]} busy, please shutdown " <<
|
||||
"the service or move occi server port."
|
||||
}
|
||||
exit -1
|
||||
end
|
||||
|
||||
set :bind, settings.config[:server]
|
||||
set :port, settings.config[:port]
|
||||
|
||||
|
||||
# Create CloudAuth
|
||||
begin
|
||||
ENV["ONE_CIPHER_AUTH"] = OCCI_AUTH
|
||||
cloud_auth = CloudAuth.new(settings.config)
|
||||
cloud_auth = CloudAuth.new(settings.config, settings.logger)
|
||||
rescue => e
|
||||
puts "Error initializing authentication system"
|
||||
puts e.message
|
||||
settings.logger.error {"Error initializing authentication system"}
|
||||
settings.logger.error {e.message}
|
||||
exit -1
|
||||
end
|
||||
|
||||
@ -110,17 +127,21 @@ before do
|
||||
begin
|
||||
username = settings.cloud_auth.auth(request.env, params)
|
||||
rescue Exception => e
|
||||
error 500, e.message
|
||||
logger.error {e.message}
|
||||
error 500, ""
|
||||
end
|
||||
else
|
||||
username = session[:user]
|
||||
end
|
||||
|
||||
if username.nil? #unable to authenticate
|
||||
logger.error {"User not authorized"}
|
||||
error 401, ""
|
||||
else
|
||||
client = settings.cloud_auth.client(username)
|
||||
@occi_server = OCCIServer.new(client, settings.config)
|
||||
@occi_server = OCCIServer.new(client,
|
||||
settings.config,
|
||||
settings.logger)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -147,20 +168,24 @@ helpers do
|
||||
begin
|
||||
username = settings.cloud_auth.auth(request.env, params)
|
||||
rescue Exception => e
|
||||
error 500, e.message
|
||||
logger.error {e.message}
|
||||
error 500, ""
|
||||
end
|
||||
|
||||
if username.nil?
|
||||
logger.error {"User not authorized"}
|
||||
error 401, ""
|
||||
else
|
||||
client = settings.cloud_auth.client(username)
|
||||
@occi_server = OCCIServer.new(client, settings.config)
|
||||
@occi_server = OCCIServer.new(client,
|
||||
settings.config,
|
||||
settings.logger)
|
||||
|
||||
user_id = OpenNebula::User::SELF
|
||||
user = OpenNebula::User.new_with_id(user_id, client)
|
||||
rc = user.info
|
||||
if OpenNebula.is_error?(rc)
|
||||
# Add a log message
|
||||
logger.error {rc.message}
|
||||
return [500, ""]
|
||||
end
|
||||
|
||||
@ -190,6 +215,7 @@ helpers do
|
||||
|
||||
def treat_response(result,rc)
|
||||
if OpenNebula::is_error?(result)
|
||||
logger.error {result.message}
|
||||
halt rc, result.message
|
||||
end
|
||||
|
||||
|
@ -132,12 +132,19 @@ div#login input#login_btn:hover {
|
||||
}
|
||||
|
||||
.error_message {
|
||||
width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
position: relative;
|
||||
top: 80px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color:red;
|
||||
font-size:1.6em;
|
||||
font-size:1.0em;
|
||||
}
|
||||
|
||||
#login_spinner {
|
||||
left: 44px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#label_remember {
|
||||
|
@ -24,14 +24,20 @@ function auth_error(req, error){
|
||||
|
||||
switch (status){
|
||||
case 401:
|
||||
$("#one_error").hide();
|
||||
$("#auth_error").fadeIn("slow");
|
||||
$("#error_box").text("Invalid username or password");
|
||||
break;
|
||||
case 500:
|
||||
$("#auth_error").hide();
|
||||
$("#one_error").fadeIn("slow");
|
||||
$("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs.");
|
||||
break;
|
||||
case 0:
|
||||
$("#error_box").text("No answer from server. Is it running?");
|
||||
break;
|
||||
default:
|
||||
$("#error_box").text("Unexpected error. Status "+status+". Check the server logs.");
|
||||
|
||||
};
|
||||
$("#error_box").fadeIn("slow");
|
||||
$("#login_spinner").hide();
|
||||
}
|
||||
|
||||
function authenticate(){
|
||||
@ -40,6 +46,9 @@ function authenticate(){
|
||||
password = Crypto.SHA1(password);
|
||||
var remember = $("#check_remember").is(":checked");
|
||||
|
||||
$("#error_box").fadeOut("slow");
|
||||
$("#login_spinner").show();
|
||||
|
||||
var obj = { data: {username: username,
|
||||
password: password},
|
||||
remember: remember,
|
||||
@ -70,4 +79,5 @@ $(document).ready(function(){
|
||||
};
|
||||
|
||||
$("input#username.box").focus();
|
||||
$("#login_spinner").hide();
|
||||
});
|
||||
|
@ -189,7 +189,7 @@ var OCCI = {
|
||||
$.ajax({
|
||||
url: resource.toLowerCase(),
|
||||
type: "GET",
|
||||
data: {timeout: timeout},
|
||||
data: {timeout: timeout, verbose: true},
|
||||
dataType: "xml ONEjson",
|
||||
success: function(response){
|
||||
var res = {};
|
||||
|
@ -153,13 +153,6 @@ var vm_actions = {
|
||||
error: onError
|
||||
},
|
||||
|
||||
"VM.showstate" : {
|
||||
type: "single",
|
||||
call: OCCI.VM.show,
|
||||
callback: updateVMStateCB,
|
||||
error: onError
|
||||
},
|
||||
|
||||
"VM.refresh" : {
|
||||
type: "custom",
|
||||
call : function (){
|
||||
@ -178,7 +171,7 @@ var vm_actions = {
|
||||
"VM.suspend" : {
|
||||
type: "multiple",
|
||||
call: OCCI.VM.suspend,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
notify: true
|
||||
@ -187,7 +180,7 @@ var vm_actions = {
|
||||
"VM.resume" : {
|
||||
type: "multiple",
|
||||
call: OCCI.VM.resume,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
notify: true
|
||||
@ -196,7 +189,7 @@ var vm_actions = {
|
||||
"VM.stop" : {
|
||||
type: "multiple",
|
||||
call: OCCI.VM.stop,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
notify: true
|
||||
@ -214,7 +207,7 @@ var vm_actions = {
|
||||
"VM.shutdown" : {
|
||||
type: "multiple",
|
||||
call: OCCI.VM.shutdown,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
notify: true
|
||||
@ -223,7 +216,7 @@ var vm_actions = {
|
||||
"VM.cancel" : {
|
||||
type: "multiple",
|
||||
call: OCCI.VM.cancel,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
elements: vmElements,
|
||||
error: onError,
|
||||
notify: true
|
||||
@ -240,7 +233,7 @@ var vm_actions = {
|
||||
"VM.saveas" : {
|
||||
type: "single",
|
||||
call: OCCI.VM.saveas,
|
||||
callback: updateVMStateCB,
|
||||
callback: updateVMachineElement,
|
||||
error:onError
|
||||
},
|
||||
|
||||
@ -259,7 +252,7 @@ var vm_actions = {
|
||||
};
|
||||
var options = "";
|
||||
for (var i = 0; i<response.length; i++){
|
||||
var type = response[i].INSTANCE_TYPE.NAME;
|
||||
var type = response[i].INSTANCE_TYPE.name;
|
||||
options += '<option value="'+type+'">'+type+'</option>';
|
||||
};
|
||||
$('#dialog select#instance_type').html(options);
|
||||
@ -423,7 +416,7 @@ function vMachineElementArray(vm_json){
|
||||
return [
|
||||
'<input class="check_item" type="checkbox" id="vm_'+id+'" name="selected_items" value="'+id+'"/>',
|
||||
id,
|
||||
name
|
||||
VMStateBulletStr(vm_json) + name
|
||||
];
|
||||
}
|
||||
|
||||
@ -473,16 +466,15 @@ function updateVMachinesView(request, vmachine_list){
|
||||
$.each(vmachine_list,function(){
|
||||
el_array = vMachineElementArray(this);
|
||||
vmachine_list_array.push(el_array);
|
||||
Sunstone.runAction("VM.showstate",el_array[1]);
|
||||
});
|
||||
|
||||
updateView(vmachine_list_array,dataTable_vMachines);
|
||||
updateDashboard("vms",vmachine_list);
|
||||
};
|
||||
|
||||
function updateVMStateCB(request,vm){
|
||||
function VMStateBulletStr(vm){
|
||||
var vm_state = vm.COMPUTE.STATE;
|
||||
var state_html = vm_state;
|
||||
var state_html = "";
|
||||
switch (vm_state) {
|
||||
case "INIT":
|
||||
case "PENDING":
|
||||
@ -499,13 +491,8 @@ function updateVMStateCB(request,vm){
|
||||
state_html = '<img style="display:inline-block;margin-right:5px;" src="images/red_bullet.png" alt="'+vm_state+'" title="'+vm_state+'"/>';
|
||||
break;
|
||||
};
|
||||
|
||||
var tag = 'input#vm_'+vm.COMPUTE.ID;
|
||||
var array = vMachineElementArray(vm);
|
||||
array[2] = state_html + array[2];
|
||||
updateSingleElement(array,dataTable_vMachines,tag);
|
||||
};
|
||||
|
||||
return state_html;
|
||||
}
|
||||
|
||||
// Refreshes the information panel for a VM
|
||||
function updateVMInfo(request,vm){
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>OpenNebula Self-Service Login</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/login.css" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="vendor/jQueryUI/jquery-ui-1.8.16.custom.css" />
|
||||
<!-- Vendor Libraries -->
|
||||
<script type="text/javascript" src="vendor/jQuery/jquery-1.7.1.min.js"></script>
|
||||
<script type="text/javascript" src="vendor/crypto-js/2.3.0-crypto-sha1.js"></script>
|
||||
@ -28,11 +28,7 @@
|
||||
<div id="logo_selfservice">
|
||||
</div>
|
||||
|
||||
<div id="auth_error" class="error_message">
|
||||
Invalid username or password
|
||||
</div>
|
||||
<div id="one_error" class="error_message">
|
||||
OpenNebula is not running
|
||||
<div id="error_box" class="error_message ui-state-error ui-corner-all">
|
||||
</div>
|
||||
|
||||
<form id="login_form">
|
||||
@ -46,7 +42,7 @@
|
||||
<input type="checkbox" id="check_remember" />
|
||||
<label id="label_remember" for="check_remember">Remember me</label>
|
||||
<input type="submit" id="login_btn" value="" />
|
||||
|
||||
<img src="images/ajax-loader.gif" alt="retrieving" id="login_spinner" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
1
src/cloud/occi/test/fixtures/compute/empty.xml
vendored
Normal file
1
src/cloud/occi/test/fixtures/compute/empty.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<COMPUTE_COLLECTION></COMPUTE_COLLECTION>
|
20
src/cloud/occi/test/fixtures/compute/first_compute.xml
vendored
Normal file
20
src/cloud/occi/test/fixtures/compute/first_compute.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<COMPUTE href="http://localhost:4567/compute/0">
|
||||
<ID>0</ID>
|
||||
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
|
||||
<GROUP>oneadmin</GROUP>
|
||||
<CPU>1</CPU>
|
||||
<MEMORY>1024</MEMORY>
|
||||
<NAME>Compute</NAME>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
|
||||
<STATE>PENDING</STATE>
|
||||
<DISK id="0">
|
||||
<STORAGE href="http://localhost:4567/storage/0" name="Storage"/>
|
||||
<TYPE>DISK</TYPE>
|
||||
<TARGET>hde</TARGET>
|
||||
</DISK>
|
||||
<NIC>
|
||||
<NETWORK href="http://localhost:4567/network/0" name="Network"/>
|
||||
<IP>192.168.1.1</IP>
|
||||
<MAC>02:00:c0:a8:01:01</MAC>
|
||||
</NIC>
|
||||
</COMPUTE>
|
20
src/cloud/occi/test/fixtures/compute/first_compute_done.xml
vendored
Normal file
20
src/cloud/occi/test/fixtures/compute/first_compute_done.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<COMPUTE href="http://localhost:4567/compute/0">
|
||||
<ID>0</ID>
|
||||
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
|
||||
<GROUP>oneadmin</GROUP>
|
||||
<CPU>1</CPU>
|
||||
<MEMORY>1024</MEMORY>
|
||||
<NAME>Compute</NAME>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
|
||||
<STATE>DONE</STATE>
|
||||
<DISK id="0">
|
||||
<STORAGE href="http://localhost:4567/storage/0" name="Storage"/>
|
||||
<TYPE>DISK</TYPE>
|
||||
<TARGET>hde</TARGET>
|
||||
</DISK>
|
||||
<NIC>
|
||||
<NETWORK href="http://localhost:4567/network/0" name="Network"/>
|
||||
<IP>192.168.1.1</IP>
|
||||
<MAC>02:00:c0:a8:01:01</MAC>
|
||||
</NIC>
|
||||
</COMPUTE>
|
20
src/cloud/occi/test/fixtures/compute/second_compute.xml
vendored
Normal file
20
src/cloud/occi/test/fixtures/compute/second_compute.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<COMPUTE href="http://localhost:4567/compute/1">
|
||||
<ID>1</ID>
|
||||
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
|
||||
<GROUP>users</GROUP>
|
||||
<CPU>1</CPU>
|
||||
<MEMORY>1024</MEMORY>
|
||||
<NAME>Compute2</NAME>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
|
||||
<STATE>PENDING</STATE>
|
||||
<DISK id="0">
|
||||
<STORAGE href="http://localhost:4567/storage/1" name="Storage2"/>
|
||||
<TYPE>DISK</TYPE>
|
||||
<TARGET>hde</TARGET>
|
||||
</DISK>
|
||||
<NIC>
|
||||
<NETWORK href="http://localhost:4567/network/1" name="Network2"/>
|
||||
<IP>192.168.2.1</IP>
|
||||
<MAC>02:00:c0:a8:02:01</MAC>
|
||||
</NIC>
|
||||
</COMPUTE>
|
20
src/cloud/occi/test/fixtures/compute/second_compute_done.xml
vendored
Normal file
20
src/cloud/occi/test/fixtures/compute/second_compute_done.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<COMPUTE href="http://localhost:4567/compute/1">
|
||||
<ID>1</ID>
|
||||
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
|
||||
<GROUP>users</GROUP>
|
||||
<CPU>1</CPU>
|
||||
<MEMORY>1024</MEMORY>
|
||||
<NAME>Compute2</NAME>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small">small</INSTANCE_TYPE>
|
||||
<STATE>DONE</STATE>
|
||||
<DISK id="0">
|
||||
<STORAGE href="http://localhost:4567/storage/1" name="Storage2"/>
|
||||
<TYPE>DISK</TYPE>
|
||||
<TARGET>hde</TARGET>
|
||||
</DISK>
|
||||
<NIC>
|
||||
<NETWORK href="http://localhost:4567/network/1" name="Network2"/>
|
||||
<IP>192.168.2.1</IP>
|
||||
<MAC>02:00:c0:a8:02:01</MAC>
|
||||
</NIC>
|
||||
</COMPUTE>
|
20
src/cloud/occi/test/fixtures/instance_type/extended.xml
vendored
Normal file
20
src/cloud/occi/test/fixtures/instance_type/extended.xml
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
<INSTANCE_TYPE_COLLECTION>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/large" name="large">
|
||||
<ID>large</ID>
|
||||
<NAME>large</NAME>
|
||||
<CPU>8</CPU>
|
||||
<MEMORY>8192</MEMORY>
|
||||
</INSTANCE_TYPE>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/medium" name="medium">
|
||||
<ID>medium</ID>
|
||||
<NAME>medium</NAME>
|
||||
<CPU>4</CPU>
|
||||
<MEMORY>4096</MEMORY>
|
||||
</INSTANCE_TYPE>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small" name="small">
|
||||
<ID>small</ID>
|
||||
<NAME>small</NAME>
|
||||
<CPU>1</CPU>
|
||||
<MEMORY>1024</MEMORY>
|
||||
</INSTANCE_TYPE>
|
||||
</INSTANCE_TYPE_COLLECTION>
|
5
src/cloud/occi/test/fixtures/instance_type/list.xml
vendored
Normal file
5
src/cloud/occi/test/fixtures/instance_type/list.xml
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<INSTANCE_TYPE_COLLECTION>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/large" name="large"/>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/medium" name="medium"/>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/small" name="small"/>
|
||||
</INSTANCE_TYPE_COLLECTION>
|
1
src/cloud/occi/test/fixtures/network/empty.xml
vendored
Normal file
1
src/cloud/occi/test/fixtures/network/empty.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<NETWORK_COLLECTION></NETWORK_COLLECTION>
|
11
src/cloud/occi/test/fixtures/network/first_net.xml
vendored
Normal file
11
src/cloud/occi/test/fixtures/network/first_net.xml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<NETWORK href="http://localhost:4567/network/0">
|
||||
<ID>0</ID>
|
||||
<NAME>Network</NAME>
|
||||
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
|
||||
<GROUP>oneadmin</GROUP>
|
||||
<DESCRIPTION>Network of the user my_first_occi_user</DESCRIPTION>
|
||||
<ADDRESS>192.168.1.1</ADDRESS>
|
||||
<SIZE>125</SIZE>
|
||||
<USED_LEASES>0</USED_LEASES>
|
||||
<PUBLIC>NO</PUBLIC>
|
||||
</NETWORK>
|
11
src/cloud/occi/test/fixtures/network/second_net.xml
vendored
Normal file
11
src/cloud/occi/test/fixtures/network/second_net.xml
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<NETWORK href="http://localhost:4567/network/1">
|
||||
<ID>1</ID>
|
||||
<NAME>Network2</NAME>
|
||||
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
|
||||
<GROUP>users</GROUP>
|
||||
<DESCRIPTION>Network of the user my_second_occi_user</DESCRIPTION>
|
||||
<ADDRESS>192.168.2.1</ADDRESS>
|
||||
<SIZE>125</SIZE>
|
||||
<USED_LEASES>0</USED_LEASES>
|
||||
<PUBLIC>NO</PUBLIC>
|
||||
</NETWORK>
|
7
src/cloud/occi/test/fixtures/root.xml
vendored
Normal file
7
src/cloud/occi/test/fixtures/root.xml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<COLLECTIONS>
|
||||
<COMPUTE_COLLECTION href="http://localhost:4567/compute"/>
|
||||
<INSTANCE_TYPE_COLLECTION href="http://localhost:4567/instance_type"/>
|
||||
<NETWORK_COLLECTION href="http://localhost:4567/network"/>
|
||||
<STORAGE_COLLECTION href="http://localhost:4567/storage"/>
|
||||
<USER_COLLECTION href="http://localhost:4567/user"/>
|
||||
</COLLECTIONS>
|
1
src/cloud/occi/test/fixtures/storage/empty.xml
vendored
Normal file
1
src/cloud/occi/test/fixtures/storage/empty.xml
vendored
Normal file
@ -0,0 +1 @@
|
||||
<STORAGE_COLLECTION></STORAGE_COLLECTION>
|
13
src/cloud/occi/test/fixtures/storage/first_storage.xml
vendored
Normal file
13
src/cloud/occi/test/fixtures/storage/first_storage.xml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<STORAGE href="http://localhost:4567/storage/0">
|
||||
<ID>0</ID>
|
||||
<NAME>Storage</NAME>
|
||||
<USER href="http://localhost:4567/user/2" name="my_first_occi_user"/>
|
||||
<GROUP>oneadmin</GROUP>
|
||||
<STATE>READY</STATE>
|
||||
<TYPE>DATABLOCK</TYPE>
|
||||
<DESCRIPTION>Storage of the user my_first_occi_user</DESCRIPTION>
|
||||
<SIZE>100</SIZE>
|
||||
<FSTYPE>ext3</FSTYPE>
|
||||
<PUBLIC>NO</PUBLIC>
|
||||
<PERSISTENT>NO</PERSISTENT>
|
||||
</STORAGE>
|
13
src/cloud/occi/test/fixtures/storage/second_storage.xml
vendored
Normal file
13
src/cloud/occi/test/fixtures/storage/second_storage.xml
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
<STORAGE href="http://localhost:4567/storage/1">
|
||||
<ID>1</ID>
|
||||
<NAME>Storage2</NAME>
|
||||
<USER href="http://localhost:4567/user/3" name="my_second_occi_user"/>
|
||||
<GROUP>users</GROUP>
|
||||
<STATE>READY</STATE>
|
||||
<TYPE>DATABLOCK</TYPE>
|
||||
<DESCRIPTION>Storage of the user my_second_occi_user</DESCRIPTION>
|
||||
<SIZE>100</SIZE>
|
||||
<FSTYPE>ext3</FSTYPE>
|
||||
<PUBLIC>NO</PUBLIC>
|
||||
<PERSISTENT>NO</PERSISTENT>
|
||||
</STORAGE>
|
283
src/cloud/occi/test/spec/occi_spec.rb
Normal file
283
src/cloud/occi/test/spec/occi_spec.rb
Normal file
@ -0,0 +1,283 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
||||
|
||||
# The following methods are helpers defined in spec_helper
|
||||
# - compare_xml
|
||||
# - get_fixture
|
||||
# - network_template
|
||||
# - storage_template
|
||||
# - compute_template
|
||||
|
||||
describe 'OCCI tests' do
|
||||
before(:all) do
|
||||
@user_oneadmin = "my_first_occi_user"
|
||||
`oneuser create #{@user_oneadmin} my_pass`.scan(/^ID: (\d+)/) { |uid|
|
||||
`oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password|
|
||||
@user_pass = password.first.strip
|
||||
}
|
||||
|
||||
`oneuser chgrp #{uid.first} 0`
|
||||
}
|
||||
|
||||
@user_users = "my_second_occi_user"
|
||||
`oneuser create #{@user_users} my_pass2`.scan(/^ID: (\d+)/) { |uid|
|
||||
`oneuser show #{uid.first}`.scan(/PASSWORD\s*:\s*(\w*)/) { |password|
|
||||
@user_pass2 = password.first.strip
|
||||
}
|
||||
}
|
||||
|
||||
# Define BRIDGE attirbute in network.erb, otherwise the NETWORK creation will
|
||||
`sed -i.bck "s%^#\\(BRIDGE = \\).*$%\\1 br0%" $ONE_LOCATION/etc/occi_templates/network.erb`
|
||||
end
|
||||
|
||||
describe "with a user of the oneadmin group" do
|
||||
before(:each) do
|
||||
basic_authorize(@user_oneadmin, @user_pass)
|
||||
end
|
||||
|
||||
it "should retrieve the list of collections" do
|
||||
get '/'
|
||||
compare_xml(last_response.body, get_fixture('/root.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should retrieve the list of INSTANCE_TYPEs" do
|
||||
get '/instance_type'
|
||||
compare_xml(last_response.body, get_fixture('/instance_type/list.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should retrieve the extended list of INSTANCE_TYPEs" do
|
||||
get '/instance_type', {'verbose'=>true}
|
||||
compare_xml(last_response.body, get_fixture('/instance_type/extended.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
context "for NETWORK" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/network'
|
||||
compare_xml(last_response.body, get_fixture('/network/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new NETWORK" do
|
||||
network = {
|
||||
:name => "Network",
|
||||
:description => "Network of the user #{@user_oneadmin}",
|
||||
:address => "192.168.1.0",
|
||||
:size => "100",
|
||||
:pubic => "YES"
|
||||
}
|
||||
|
||||
post '/network', network_template(network)
|
||||
compare_xml(last_response.body, get_fixture('/network/first_net.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the NETWORK with ID 0" do
|
||||
get '/network/0'
|
||||
compare_xml(last_response.body, get_fixture('/network/first_net.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
end
|
||||
|
||||
context "for STORAGE" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/storage'
|
||||
compare_xml(last_response.body, get_fixture('/storage/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do
|
||||
storage = {
|
||||
:name => "Storage",
|
||||
:description => "Storage of the user #{@user_oneadmin}",
|
||||
:type => "DATABLOCK",
|
||||
:size => "100",
|
||||
:fstype => "ext3"
|
||||
}
|
||||
|
||||
post '/storage', {'occixml' => storage_template(storage)}
|
||||
compare_xml(last_response.body, get_fixture('/storage/first_storage.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the STORAGE with ID 0" do
|
||||
get '/storage/0'
|
||||
compare_xml(last_response.body, get_fixture('/storage/first_storage.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
end
|
||||
|
||||
context "for COMPUTE" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/compute'
|
||||
compare_xml(last_response.body, get_fixture('/compute/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new COMPUTE using the previous NETWORK (ID=0) and STORAGE(ID=0)" do
|
||||
compute = {
|
||||
:name => "Compute",
|
||||
:instance_type => "small",
|
||||
:disk => [ {:storage => '0'} ],
|
||||
:nic => [ {:network => '0'} ]
|
||||
}
|
||||
|
||||
post '/compute', compute_template(compute)
|
||||
compare_xml(last_response.body, get_fixture('/compute/first_compute.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the COMPUTE with ID 0" do
|
||||
get '/compute/0'
|
||||
compare_xml(last_response.body, get_fixture('/compute/first_compute.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should terminate (DONE) the COMPUTE with ID 0" do
|
||||
compute = {
|
||||
:id => "0",
|
||||
:state => "DONE"
|
||||
}
|
||||
|
||||
put '/compute/0', compute_action(compute)
|
||||
compare_xml(last_response.body, get_fixture('/compute/first_compute_done.xml'))
|
||||
last_response.status.should == 202
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "with a user of the users group" do
|
||||
before(:each) do
|
||||
basic_authorize(@user_users, @user_pass2)
|
||||
end
|
||||
|
||||
it "should retrieve the list of collections" do
|
||||
get '/'
|
||||
compare_xml(last_response.body, get_fixture('/root.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should retrieve the list of INSTANCE_TYPEs" do
|
||||
get '/instance_type'
|
||||
compare_xml(last_response.body, get_fixture('/instance_type/list.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should retrieve the extended list of INSTANCE_TYPEs" do
|
||||
get '/instance_type', {'verbose'=>true}
|
||||
compare_xml(last_response.body, get_fixture('/instance_type/extended.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
context "for NETWORK" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/network'
|
||||
compare_xml(last_response.body, get_fixture('/network/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new NETWORK" do
|
||||
network = {
|
||||
:name => "Network2",
|
||||
:description => "Network of the user #{@user_users}",
|
||||
:address => "192.168.2.0",
|
||||
:size => "100",
|
||||
:pubic => "YES"
|
||||
}
|
||||
|
||||
post '/network', network_template(network)
|
||||
compare_xml(last_response.body, get_fixture('/network/second_net.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the NETWORK with ID 1" do
|
||||
get '/network/1'
|
||||
compare_xml(last_response.body, get_fixture('/network/second_net.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
end
|
||||
|
||||
context "for STORAGE" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/storage'
|
||||
compare_xml(last_response.body, get_fixture('/storage/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new STORAGE, type DATABLOCK. This request waits until the IMAGE is ready in OpenNebula" do
|
||||
storage = {
|
||||
:name => "Storage2",
|
||||
:description => "Storage of the user #{@user_users}",
|
||||
:type => "DATABLOCK",
|
||||
:size => "100",
|
||||
:fstype => "ext3"
|
||||
}
|
||||
|
||||
post '/storage', {'occixml' => storage_template(storage)}
|
||||
compare_xml(last_response.body, get_fixture('/storage/second_storage.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the STORAGE with ID 1" do
|
||||
get '/storage/1'
|
||||
compare_xml(last_response.body, get_fixture('/storage/second_storage.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
end
|
||||
|
||||
context "for COMPUTE" do
|
||||
it "should retrieve the empty list" do
|
||||
get '/compute'
|
||||
compare_xml(last_response.body, get_fixture('/compute/empty.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should create a new COMPUTE using the previous NETWORK (ID=1) and STORAGE(ID=1)" do
|
||||
compute = {
|
||||
:name => "Compute2",
|
||||
:instance_type => "small",
|
||||
:disk => [ {:storage => '1'} ],
|
||||
:nic => [ {:network => '1'} ]
|
||||
}
|
||||
|
||||
post '/compute', compute_template(compute)
|
||||
compare_xml(last_response.body, get_fixture('/compute/second_compute.xml'))
|
||||
last_response.status.should == 201
|
||||
end
|
||||
|
||||
it "should retrieve the COMPUTE with ID 1" do
|
||||
get '/compute/1'
|
||||
compare_xml(last_response.body, get_fixture('/compute/second_compute.xml'))
|
||||
last_response.status.should == 200
|
||||
end
|
||||
|
||||
it "should terminate (DONE) the COMPUTE with ID 1" do
|
||||
compute = {
|
||||
:id => "1",
|
||||
:state => "DONE"
|
||||
}
|
||||
|
||||
put '/compute/1', compute_action(compute)
|
||||
compare_xml(last_response.body, get_fixture('/compute/second_compute_done.xml'))
|
||||
last_response.status.should == 202
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
4
src/cloud/occi/test/spec/spec.opts
Normal file
4
src/cloud/occi/test/spec/spec.opts
Normal file
@ -0,0 +1,4 @@
|
||||
--colour
|
||||
--format progress
|
||||
--loadby mtime
|
||||
--reverse
|
@ -24,6 +24,8 @@ require 'rubygems'
|
||||
require 'rspec'
|
||||
require 'rack/test'
|
||||
|
||||
require 'rexml/document'
|
||||
|
||||
# Load the Sinatra app
|
||||
require 'occi-server'
|
||||
|
||||
@ -39,3 +41,153 @@ set :environment, :test
|
||||
def app
|
||||
Sinatra::Application
|
||||
end
|
||||
|
||||
|
||||
|
||||
def get_fixture(path)
|
||||
File.read(FIXTURES_PATH + path).strip
|
||||
end
|
||||
|
||||
|
||||
def compare_xml(a, b)
|
||||
a = REXML::Document.new(a.to_s)
|
||||
b = REXML::Document.new(b.to_s)
|
||||
|
||||
normalized = Class.new(REXML::Formatters::Pretty) do
|
||||
def write_text(node, output)
|
||||
super(node.to_s.strip, output)
|
||||
end
|
||||
end
|
||||
|
||||
normalized.new(indentation=0,ie_hack=false).write(node=a, a_normalized='')
|
||||
normalized.new(indentation=0,ie_hack=false).write(node=b, b_normalized='')
|
||||
|
||||
a_normalized.should == b_normalized
|
||||
end
|
||||
|
||||
|
||||
OCCI_NETWORK = %q{
|
||||
<NETWORK>
|
||||
<% if hash[:name] %>
|
||||
<NAME><%= hash[:name] %></NAME>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:description] %>
|
||||
<DESCRIPTION><%= hash[:description] %></DESCRIPTION>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:address] %>
|
||||
<ADDRESS><%= hash[:address] %></ADDRESS>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:size] %>
|
||||
<SIZE><%= hash[:size] %></SIZE>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:public] %>
|
||||
<PUBLIC><%= hash[:public] %></PUBLIC>
|
||||
<% end %>
|
||||
</NETWORK>
|
||||
}
|
||||
|
||||
def network_template(hash)
|
||||
ERB.new(OCCI_NETWORK).result(binding)
|
||||
end
|
||||
|
||||
OCCI_IMAGE = %q{
|
||||
<STORAGE>
|
||||
<% if hash[:name] %>
|
||||
<NAME><%= hash[:name] %></NAME>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:type] %>
|
||||
<TYPE><%= hash[:type] %></TYPE>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:description] %>
|
||||
<DESCRIPTION><%= hash[:description] %></DESCRIPTION>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:size] %>
|
||||
<SIZE><%= hash[:size] %></SIZE>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:fstype] %>
|
||||
<FSTYPE><%= hash[:fstype] %></FSTYPE>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:public] %>
|
||||
<PUBLIC><%= hash[:public] %></PUBLIC>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:persistent] %>
|
||||
<PERSISTENT><%= hash[:persistent] %></PERSISTENT>
|
||||
<% end %>
|
||||
</STORAGE>
|
||||
}
|
||||
|
||||
def storage_template(hash)
|
||||
ERB.new(OCCI_IMAGE).result(binding)
|
||||
end
|
||||
|
||||
OCCI_VM = %q{
|
||||
<COMPUTE>
|
||||
<% if hash[:name] %>
|
||||
<NAME><%= hash[:name] %></NAME>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:instance_type] %>
|
||||
<INSTANCE_TYPE href="http://localhost:4567/instance_type/<%= hash[:instance_type] %>"/>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:disk] %>
|
||||
<% hash[:disk].each { |disk| %>
|
||||
<DISK>
|
||||
<% if disk[:storage] %>
|
||||
<STORAGE href="http://localhost:4567/storage/<%= disk[:storage] %>"/>
|
||||
<% end %>
|
||||
</DISK>
|
||||
<% } %>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:nic] %>
|
||||
<% hash[:nic].each { |nic| %>
|
||||
<NIC>
|
||||
<% if nic[:network] %>
|
||||
<NETWORK href="http://localhost:4567/network/<%= nic[:network] %>"/>
|
||||
<% end %>
|
||||
<% if nic[:ip] %>
|
||||
<IP><%= nic[:ip] %></IP>
|
||||
<% end %>
|
||||
</NIC>
|
||||
<% } %>
|
||||
<% end %>
|
||||
|
||||
<% if hash[:context] %>
|
||||
<CONTEXT>
|
||||
<% hash[:context].each { |key, value| %>
|
||||
<<%= key.to_s.upcase %>><%= value %></<%= key.to_s.upcase %>>
|
||||
<% } %>
|
||||
</CONTEXT>
|
||||
<% end %>
|
||||
</COMPUTE>
|
||||
}
|
||||
|
||||
OCCI_VM_ACTION = %q{
|
||||
<COMPUTE>
|
||||
<% if hash[:id] %>
|
||||
<ID><%= hash[:id] %></ID>
|
||||
<% end %>
|
||||
<% if hash[:state] %>
|
||||
<STATE><%= hash[:state] %></STATE>
|
||||
<% end %>
|
||||
</COMPUTE>
|
||||
}
|
||||
|
||||
def compute_template(hash)
|
||||
ERB.new(OCCI_VM).result(binding)
|
||||
end
|
||||
|
||||
def compute_action(hash)
|
||||
ERB.new(OCCI_VM_ACTION).result(binding)
|
||||
end
|
||||
|
@ -106,7 +106,7 @@ conf = YAML::load(File.read(CONF_FILE))
|
||||
rc, data = do_action("virsh -c #{@uri} --readonly nodeinfo")
|
||||
|
||||
if rc == false
|
||||
exit info
|
||||
exit data
|
||||
end
|
||||
|
||||
data.split(/\n/).each{|line|
|
||||
|
@ -61,11 +61,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
helper.create_resource(args[0], options)
|
||||
end
|
||||
|
||||
command :show, 'Show information of a particular VDC', :vdcid do
|
||||
command :show, 'Show information of a particular VDC', :vdcid,
|
||||
:options => OZonesHelper::JSON do
|
||||
helper.show_resource(args[0],options)
|
||||
end
|
||||
|
||||
command :list, 'Lists VDCs in the pool' do
|
||||
command :list, 'Lists VDCs in the pool', :options => OZonesHelper::JSON do
|
||||
helper.list_pool(options)
|
||||
end
|
||||
|
||||
|
@ -71,8 +71,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
onezone show 4 host
|
||||
EOT
|
||||
|
||||
command :show, show_desc, :zoneid, [:resource, nil] do
|
||||
zone=helper.show_resource(args[0],options)[1]
|
||||
command :show, show_desc, :zoneid, [:resource, nil],
|
||||
:options => OZonesHelper::JSON do
|
||||
zone = helper.show_resource(args[0],options)[1]
|
||||
|
||||
#manually print here
|
||||
if options[:json]
|
||||
puts zone
|
||||
end
|
||||
|
||||
if !args[1] then next 0 end
|
||||
|
||||
case args[1]
|
||||
when "host"
|
||||
@ -87,35 +95,41 @@ cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
aux_helper = OneTemplateHelper.new
|
||||
when "user"
|
||||
aux_helper = OneUserHelper.new
|
||||
else
|
||||
puts "\n:!: Pool #{args[1]} doesn't exist or is not supported\n\n"
|
||||
next 0
|
||||
else
|
||||
puts "\n:!: Pool #{args[1]} doesn't exist or is not supported\n\n"
|
||||
next 0
|
||||
end
|
||||
|
||||
pool_hash_data = helper.get_resource_pool("zone", zone[:ID], args[1])
|
||||
pool_hash_data = helper.get_resource_pool("zone", args[0], args[1],
|
||||
options)
|
||||
|
||||
if pool_hash_data[0] != 0
|
||||
puts "\nError retrieving information for pool #{args[1]}. Reason: " + pool_hash_data[1] + "\n\n"
|
||||
if pool_hash_data[0] != 0
|
||||
puts "\nError retrieving information for pool #{args[1]}. Reason: " + pool_hash_data[1] + "\n\n"
|
||||
next 0
|
||||
end
|
||||
end
|
||||
|
||||
if !pool_hash_data[1]
|
||||
next 0
|
||||
if !pool_hash_data[1]
|
||||
next 0
|
||||
end
|
||||
|
||||
if options[:json]
|
||||
puts pool_hash_data[1]
|
||||
next 0
|
||||
end
|
||||
|
||||
if pool_hash_data[1].is_a?(Hash)
|
||||
pool_hash_data[1]=[Hash.transform_keys_to_strings(pool_hash_data[1])]
|
||||
else
|
||||
pool_hash_data[1].each{|hash| hash.replace(Hash.transform_keys_to_strings(hash))}
|
||||
else
|
||||
pool_hash_data[1].each{|hash| hash.replace(Hash.transform_keys_to_strings(hash))}
|
||||
end
|
||||
|
||||
table = aux_helper.format_pool(options)
|
||||
table.show(pool_hash_data[1])
|
||||
table.show(pool_hash_data[1])
|
||||
|
||||
0
|
||||
end
|
||||
|
||||
command :list, 'Lists Zones in the pool' do
|
||||
command :list, 'Lists Zones in the pool', :options=>OZonesHelper::JSON do
|
||||
helper.list_pool(options)
|
||||
end
|
||||
|
||||
|
@ -18,6 +18,15 @@ require 'zona'
|
||||
|
||||
module OZonesHelper
|
||||
|
||||
#Specific ozones CLI options
|
||||
|
||||
JSON={
|
||||
:name => "json",
|
||||
:short => "-j",
|
||||
:large => "--json",
|
||||
:description => "Show the resource in JSON format"
|
||||
}
|
||||
|
||||
class OZHelper
|
||||
def initialize(user=nil, pass=nil, endpoint_str=nil,
|
||||
timeout=nil, debug_flag=true)
|
||||
@ -45,8 +54,13 @@ module OZonesHelper
|
||||
if Zona::is_error?(rc)
|
||||
[-1, rc.message]
|
||||
else
|
||||
pool=Zona::OZonesJSON.parse_json(rc.body, kind.upcase + "_POOL")
|
||||
format_pool(pool, options)
|
||||
if options[:json]
|
||||
[0, rc.body]
|
||||
else
|
||||
resource_str = kind.upcase + "_POOL"
|
||||
pool=Zona::OZonesJSON.parse_json(rc.body, resource_str)
|
||||
format_pool(pool, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -56,18 +70,26 @@ module OZonesHelper
|
||||
if Zona::is_error?(rc)
|
||||
[-1, rc.message]
|
||||
else
|
||||
resource=Zona::OZonesJSON.parse_json(rc.body, kind.upcase)
|
||||
format_resource(resource, options)
|
||||
if options[:json]
|
||||
[0, rc.body]
|
||||
else
|
||||
resource=Zona::OZonesJSON.parse_json(rc.body, kind.upcase)
|
||||
format_resource(resource, options)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def get_resource_pool(kind, id, pool)
|
||||
def get_resource_pool(kind, id, pool, options)
|
||||
rc = @client.get_resource_pool(kind, id, pool)
|
||||
|
||||
if Zona::is_error?(rc)
|
||||
[-1, rc.message]
|
||||
else
|
||||
[0 , Zona::OZonesJSON.parse_json(rc.body, pool.upcase+"_POOL")[pool.upcase.to_sym]]
|
||||
if options[:json]
|
||||
[0, rc.body]
|
||||
else
|
||||
[0 , Zona::OZonesJSON.parse_json(rc.body, pool.upcase+"_POOL")[pool.upcase.to_sym]]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -19,14 +19,14 @@
|
||||
if [ -z "$ONE_LOCATION" ]; then
|
||||
OZONES_PID=/var/run/one/ozones.pid
|
||||
OZONES_LOCATION=/usr/lib/one/ozones
|
||||
OZONES_SERVER=$OZONES_LOCATION/config.ru
|
||||
OZONES_SERVER=$OZONES_LOCATION/ozones-server.rb
|
||||
OZONES_LOCK_FILE=/var/lock/one/.ozones.lock
|
||||
OZONES_LOG=/var/log/one/ozones-server.log
|
||||
OZONES_CONF=/etc/one/ozones-server.conf
|
||||
else
|
||||
OZONES_PID=$ONE_LOCATION/var/ozones.pid
|
||||
OZONES_LOCATION=$ONE_LOCATION/lib/ozones
|
||||
OZONES_SERVER=$OZONES_LOCATION/config.ru
|
||||
OZONES_SERVER=$OZONES_LOCATION/ozones-server.rb
|
||||
OZONES_LOCK_FILE=$ONE_LOCATION/var/.ozones.lock
|
||||
OZONES_LOG=$ONE_LOCATION/var/ozones-server.log
|
||||
OZONES_CONF=$ONE_LOCATION/etc/ozones-server.conf
|
||||
@ -58,29 +58,26 @@ start()
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HOST=`cat $OZONES_CONF|grep ^\:host\:|cut -d' ' -f 2`
|
||||
PORT=`cat $OZONES_CONF|grep ^\:port\:|cut -d' ' -f 2`
|
||||
|
||||
lsof -i:$PORT &> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "The port $PORT is being used. Please specify a different one."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start the ozones daemon
|
||||
touch $OZONES_LOCK_FILE
|
||||
rackup $OZONES_SERVER -s thin -p $PORT -o $HOST \
|
||||
-P $OZONES_PID &> $OZONES_LOG &
|
||||
ruby $OZONES_SERVER > $OZONES_LOG 2>&1 &
|
||||
LASTPID=$!
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error executing $OZONES_SERVER, please check the log $OZONES_LOG"
|
||||
exit 1
|
||||
else
|
||||
echo $LASTPID > $OZONES_PID
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
ps -p $(cat $OZONES_PID 2>/dev/null) > /dev/null 2>&1
|
||||
ps $LASTPID &> /dev/null
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Error executing $OZONES_SERVER, please check the log $OZONES_LOG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "ozones-server listening on $HOST:$PORT"
|
||||
echo "ozones-server started"
|
||||
}
|
||||
|
||||
#
|
||||
|
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'ozones-server.rb'
|
||||
|
||||
run Sinatra::Application
|
@ -19,13 +19,17 @@
|
||||
##############################################
|
||||
|
||||
######################
|
||||
# DB Options
|
||||
# DB Options
|
||||
######################
|
||||
|
||||
:databasetype: sqlite
|
||||
#:databaseserver: dbuser:dbpassword@localhost
|
||||
#:htaccess: /var/www/.htaccess
|
||||
:dbdebug: no
|
||||
|
||||
# 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
:debug_level: 3
|
||||
|
||||
#####################
|
||||
# Server Configuration
|
||||
#####################
|
||||
|
@ -28,12 +28,20 @@ module OZones
|
||||
zone.vdcs.all.each{|vdc|
|
||||
htaccess << "RewriteRule ^#{vdc.NAME} " +
|
||||
"#{zone.ENDPOINT} [P]\n"
|
||||
|
||||
if zone.SUNSENDPOINT != nil
|
||||
htaccess << "RewriteRule ^sunstone_#{vdc.NAME}/(.+) " +
|
||||
"#{zone.SUNSENDPOINT}/$1 [P]\n"
|
||||
htaccess << "RewriteRule ^sunstone_#{vdc.NAME} " +
|
||||
"#{zone.SUNSENDPOINT}/ [P]\n"
|
||||
end
|
||||
|
||||
if zone.SELFENDPOINT != nil
|
||||
htaccess << "RewriteRule ^self_#{vdc.NAME}/(.+) " +
|
||||
"#{zone.SELFENDPOINT}/$1 [P]\n"
|
||||
htaccess << "RewriteRule ^self_#{vdc.NAME} " +
|
||||
"#{zone.SELFENDPOINT}/ [P]\n"
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ module OZones
|
||||
property :ONEPASS, String, :required => true
|
||||
property :ENDPOINT, String, :required => true
|
||||
property :SUNSENDPOINT, String
|
||||
property :SELFENDPOINT, String
|
||||
|
||||
has n, :vdcs
|
||||
|
||||
|
@ -14,13 +14,16 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'CloudServer'
|
||||
|
||||
require 'JSONUtils'
|
||||
|
||||
|
||||
class OzonesServer
|
||||
class OzonesServer < CloudServer
|
||||
include OpenNebulaJSON::JSONUtils
|
||||
|
||||
def initialize(cipher)
|
||||
def initialize(cipher, config, logger)
|
||||
super(config, logger)
|
||||
#Set cipher for Zone classes
|
||||
OZones::Zones.cipher = cipher
|
||||
end
|
||||
|
@ -19,19 +19,25 @@
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
ETC_LOCATION="/etc/one"
|
||||
LIB_LOCATION="/usr/lib/one"
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
VAR_LOCATION="/var/lib/one"
|
||||
LOG_LOCATION = "/var/log/one"
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
LIB_LOCATION = "/usr/lib/one"
|
||||
RUBY_LIB_LOCATION = "/usr/lib/one/ruby"
|
||||
else
|
||||
ETC_LOCATION=ONE_LOCATION+"/etc"
|
||||
LIB_LOCATION=ONE_LOCATION+"/lib"
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
VAR_LOCATION=ONE_LOCATION+"/var"
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
LOG_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
LIB_LOCATION = ONE_LOCATION+"/lib"
|
||||
RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
OZONES_LOG = LOG_LOCATION + "/ozones-server.log"
|
||||
CONFIGURATION_FILE = ETC_LOCATION + "/ozones-server.conf"
|
||||
|
||||
$: << LIB_LOCATION + "/sunstone/models"
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+'/cloud'
|
||||
$: << LIB_LOCATION+'/ozones/models'
|
||||
$: << LIB_LOCATION+'/ozones/lib'
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
@ -52,12 +58,46 @@ require 'OzonesServer'
|
||||
##############################################################################
|
||||
# Read configuration
|
||||
##############################################################################
|
||||
config_data=File.read(ETC_LOCATION+'/ozones-server.conf')
|
||||
config=YAML::load(config_data)
|
||||
begin
|
||||
config=YAML::load_file(CONFIGURATION_FILE)
|
||||
rescue Exception => e
|
||||
warn "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
config[:debug_level] ||= 3
|
||||
|
||||
CloudServer.print_configuration(config)
|
||||
|
||||
db_type = config[:databasetype]
|
||||
|
||||
db_url = db_type + "://" + VAR_LOCATION + "/ozones.db"
|
||||
case db_type
|
||||
when "sqlite" then
|
||||
db_url = db_type + "://" + VAR_LOCATION + "/ozones.db"
|
||||
when "mysql","postgres" then
|
||||
if config[:databaseserver].nil?
|
||||
warn "DB server needed for this type of DB backend"
|
||||
exit -1
|
||||
end
|
||||
|
||||
db_url = db_type + "://" + config[:databaseserver] + "/ozones"
|
||||
else
|
||||
warn "DB type #{db_type} not recognized"
|
||||
exit -1
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Sinatra Configuration
|
||||
##############################################################################
|
||||
set :config, config
|
||||
set :bind, config[:host]
|
||||
set :port, config[:port]
|
||||
|
||||
use Rack::Session::Pool, :key => 'ozones'
|
||||
|
||||
#Enable logger
|
||||
include CloudLogger
|
||||
enable_logging OZONES_LOG, settings.config[:debug_level].to_i
|
||||
|
||||
##############################################################################
|
||||
# DB bootstrapping
|
||||
@ -79,7 +119,7 @@ if Auth.all.size == 0
|
||||
credentials = IO.read(ENV['OZONES_AUTH']).strip.split(':')
|
||||
|
||||
if credentials.length < 2
|
||||
warn "Authorization data malformed"
|
||||
settings.logger.error {"Authorization data malformed"}
|
||||
exit -1
|
||||
end
|
||||
credentials[1] = Digest::SHA1.hexdigest(credentials[1])
|
||||
@ -87,7 +127,8 @@ if Auth.all.size == 0
|
||||
:password => credentials[1]})
|
||||
@auth.save
|
||||
else
|
||||
warn "oZones admin credentials not set, missing OZONES_AUTH file."
|
||||
error_m = "oZones admin credentials not set, missing OZONES_AUTH file."
|
||||
settings.logger.error { error_m }
|
||||
exit -1
|
||||
end
|
||||
else
|
||||
@ -100,19 +141,10 @@ ADMIN_PASS = @auth.password
|
||||
begin
|
||||
OZones::ProxyRules.new("apache",config[:htaccess])
|
||||
rescue Exception => e
|
||||
warn e.message
|
||||
settings.logger {e.message}
|
||||
exit -1
|
||||
end
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Sinatra Configuration
|
||||
##############################################################################
|
||||
use Rack::Session::Pool, :key => 'ozones'
|
||||
set :bind, config[:host]
|
||||
set :port, config[:port]
|
||||
set :show_exceptions, false
|
||||
|
||||
##############################################################################
|
||||
# Helpers
|
||||
##############################################################################
|
||||
@ -144,10 +176,11 @@ helpers do
|
||||
|
||||
return [204, ""]
|
||||
else
|
||||
logger.info {"User not authorized login attempt"}
|
||||
return [401, ""]
|
||||
end
|
||||
end
|
||||
|
||||
logger.error {"Authentication settings wrong or not provided"}
|
||||
return [401, ""]
|
||||
end
|
||||
|
||||
@ -168,7 +201,9 @@ before do
|
||||
end
|
||||
end
|
||||
|
||||
@OzonesServer = OzonesServer.new(session[:key])
|
||||
@OzonesServer = OzonesServer.new(session[:key],
|
||||
settings.config,
|
||||
settings.logger)
|
||||
@pr = OZones::ProxyRules.new("apache",config[:htaccess])
|
||||
end
|
||||
end
|
||||
|
@ -133,12 +133,19 @@ div#login input#login_btn:hover {
|
||||
}
|
||||
|
||||
.error_message {
|
||||
width: 400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
display: none;
|
||||
position: relative;
|
||||
top: 80px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color:red;
|
||||
font-size:1.6em;
|
||||
font-size:1.0em;
|
||||
}
|
||||
|
||||
#login_spinner {
|
||||
left: 44px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#label_remember {
|
||||
|
@ -23,15 +23,21 @@ function auth_error(req, error){
|
||||
var status = error.error.http_status;
|
||||
|
||||
switch (status){
|
||||
case 401:
|
||||
$("#one_error").hide();
|
||||
$("#auth_error").fadeIn("slow");
|
||||
break;
|
||||
case 500:
|
||||
$("#auth_error").hide();
|
||||
$("#one_error").fadeIn("slow");
|
||||
break;
|
||||
}
|
||||
case 401:
|
||||
$("#error_box").text("Invalid username or password");
|
||||
break;
|
||||
case 500:
|
||||
$("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs.");
|
||||
break;
|
||||
case 0:
|
||||
$("#error_box").text("No answer from server. Is it running?");
|
||||
break;
|
||||
default:
|
||||
$("#error_box").text("Unexpected error. Status "+status+". Check the server logs.");
|
||||
|
||||
};
|
||||
$("#error_box").fadeIn("slow");
|
||||
$("#login_spinner").hide();
|
||||
}
|
||||
|
||||
function authenticate(){
|
||||
@ -39,6 +45,9 @@ function authenticate(){
|
||||
var password = $("#password").val();
|
||||
var remember = $("#check_remember").is(":checked");
|
||||
|
||||
$("#error_box").fadeOut("slow");
|
||||
$("#login_spinner").show();
|
||||
|
||||
oZones.Auth.login({ data: {username: username
|
||||
, password: password}
|
||||
, remember: remember
|
||||
@ -61,4 +70,5 @@ $(document).ready(function(){
|
||||
};
|
||||
|
||||
$("input#username.box").focus();
|
||||
$("#login_spinner").hide();
|
||||
});
|
||||
|
@ -282,12 +282,14 @@ function updateVDCInfo(req,vdc_json){
|
||||
var zone_host = "";
|
||||
var zone_port = "";
|
||||
var sun_link = "";
|
||||
var self_link = "";
|
||||
var zone_match = zone_endpoint.match(/^https?:\/\/([\w.-]+):(\d+)\/([\W\w]+)$/);
|
||||
|
||||
if (zone_match){
|
||||
zone_host = zone_match[1];
|
||||
zone_port = zone_match[2];
|
||||
sun_link = "http://" + zone_host +"/sunstone_"+ vdc.NAME+"/";
|
||||
self_link = "http://" + zone_host +"/self_"+ vdc.NAME+"/";
|
||||
};
|
||||
|
||||
var info_tab = {
|
||||
@ -330,6 +332,10 @@ function updateVDCInfo(req,vdc_json){
|
||||
<td class="key_td">Sunstone public link</td>\
|
||||
<td class="value_td">'+(sun_link.length? '<a href="'+sun_link+'" target="_blank">'+sun_link+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">SelfService public link</td>\
|
||||
<td class="value_td">'+(self_link.length? '<a href="'+self_link+'" target="_blank">'+self_link+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "")+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">ONE_XMLPRC (to export for CLI access)</td>\
|
||||
<td class="value_td"><input type="text" id="one_xmlrpc" value="'+(zone_host.length? "http://" + zone_host +"/"+ vdc.NAME: "--")+'" style="width:100%;"/></td>\
|
||||
@ -501,12 +507,10 @@ function setupCreateVDCDialog(){
|
||||
"ZONEID" : zoneid,
|
||||
"VDCADMINNAME" : vdcadminname,
|
||||
"VDCADMINPASS" : vdcadminpass,
|
||||
"FORCE" : force
|
||||
"FORCE" : force,
|
||||
"HOSTS" : hosts
|
||||
}
|
||||
};
|
||||
if (hosts.length){
|
||||
vdc_json["VDC"]["HOSTS"]=hosts;
|
||||
};
|
||||
|
||||
Sunstone.runAction("VDC.create",vdc_json);
|
||||
dialog.dialog('close');
|
||||
@ -516,6 +520,10 @@ function setupCreateVDCDialog(){
|
||||
|
||||
function openCreateVDCDialog(){
|
||||
var dialog = $('div#create_vdc_dialog')
|
||||
if (!zones_select){
|
||||
notifyError(tr("No zones defined: You need to create at least 1 zone before creating an VDC"));
|
||||
return false;
|
||||
};
|
||||
$('select#zoneid',dialog).html(zones_select);
|
||||
$('select#zoneid',dialog).trigger("change");
|
||||
$('#vdc_available_hosts_list',dialog).empty();
|
||||
|
@ -53,6 +53,12 @@ var create_zone_tmpl =
|
||||
<input type="text" name="sunsendpoint_port" id="sunsendpoint_port" value="9869" style="width:3em;"/> /\
|
||||
<input type="text" name="sunsendpoint_path" id="sunsendpoint_path" value="" style="width:4em;"/>\
|
||||
<br />\
|
||||
<label for="selfsendpoint">SelfService end point:</label>\
|
||||
<input type="text" name="selfsendpoint_ptc" id="selfsendpoint_ptc" value="http" style="width:2em;"/> ://\
|
||||
<input type="text" name="selfsendpoint" id="selfsendpoint" style="width:7em;" value="localhost"/> :\
|
||||
<input type="text" name="selfsendpoint_port" id="selfsendpoint_port" value="4567" style="width:3em;"/> /\
|
||||
<input type="text" name="selfsendpoint_path" id="selfsendpoint_path" value="ui" style="width:4em;"/>\
|
||||
<br />\
|
||||
</div>\
|
||||
</fieldset>\
|
||||
<fieldset>\
|
||||
@ -310,8 +316,12 @@ function updateZoneInfo(req,zone_json){
|
||||
<td class="value_td">'+zone.ENDPOINT+'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">Sunstone endpoint</td>\
|
||||
<td class="value_td">'+ (zone.SUNSENDPOINT.length? '<a href="'+zone.SUNSENDPOINT+'" target="_blank">'+zone.SUNSENDPOINT+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "") +'</td>\
|
||||
<td class="key_td">Sunstone endpoint</td>\
|
||||
<td class="value_td">'+ (zone.SUNSENDPOINT.length? '<a href="'+zone.SUNSENDPOINT+'" target="_blank">'+zone.SUNSENDPOINT+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "") +'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">SelfService endpoint</td>\
|
||||
<td class="value_td">'+ (zone.SELFENDPOINT.length? '<a href="'+zone.SELFENDPOINT+'" target="_blank">'+zone.SELFENDPOINT+'<span class="ui-icon ui-icon-extlink" style="display:inline-block;" /></a>' : "") +'</td>\
|
||||
</tr>\
|
||||
<tr>\
|
||||
<td class="key_td">#VDCs</td>\
|
||||
@ -557,11 +567,17 @@ function setupCreateZoneDialog(){
|
||||
var endpoint_port = $('#endpoint_port',this).val();
|
||||
var onename = $('#onename',this).val();
|
||||
var onepass = $('#onepass',this).val();
|
||||
|
||||
var se = $('#sunsendpoint',this).val();
|
||||
var se_ptc = $('#sunsendpoint_ptc',this).val();
|
||||
var se_port = $('#sunsendpoint_port',this).val();
|
||||
var se_path = $('#sunsendpoint_path',this).val();
|
||||
|
||||
var ss = $('#selfsendpoint',this).val();
|
||||
var ss_ptc = $('#selfsendpoint_ptc',this).val();
|
||||
var ss_port = $('#selfsendpoint_port',this).val();
|
||||
var ss_path = $('#selfsendpoint_path',this).val();
|
||||
|
||||
if (!name.length || !endpoint.length ||
|
||||
!onename.length || !onepass.length){
|
||||
notifyError("Please fill in all fields");
|
||||
@ -575,13 +591,18 @@ function setupCreateZoneDialog(){
|
||||
se = se_ptc + "://" + se + ":" + se_port +
|
||||
"/" + se_path;
|
||||
|
||||
if (ss.length)
|
||||
ss = ss_ptc + "://" + ss + ":" + ss_port +
|
||||
"/" + ss_path;
|
||||
|
||||
var zone_json = {
|
||||
"ZONE": {
|
||||
"NAME": name,
|
||||
"ENDPOINT": endpoint,
|
||||
"ONENAME": onename,
|
||||
"ONEPASS": onepass,
|
||||
"SUNSENDPOINT" : se
|
||||
"SUNSENDPOINT" : se,
|
||||
"SELFENDPOINT" : ss,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>OpenNebula oZones Login</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/login.css" />
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="vendor/jQueryUI/jquery-ui-1.8.16.custom.css" />
|
||||
<!-- Vendor Libraries -->
|
||||
<script type="text/javascript" src="vendor/jQuery/jquery-1.7.1.min.js"></script>
|
||||
<!-- End Vendor Libraries -->
|
||||
@ -24,11 +24,7 @@
|
||||
<div id="logo_sunstone">
|
||||
</div>
|
||||
|
||||
<div id="auth_error" class="error_message">
|
||||
Invalid username or password
|
||||
</div>
|
||||
<div id="one_error" class="error_message">
|
||||
OpenNebula is not running
|
||||
<div id="error_box" class="error_message ui-state-error ui-corner-all">
|
||||
</div>
|
||||
|
||||
<form id="login_form">
|
||||
@ -42,6 +38,7 @@
|
||||
<input type="checkbox" id="check_remember">
|
||||
<label id="label_remember" for="check_remember">Remember me</label>
|
||||
<input type="submit" id="login_btn" value="" />
|
||||
<img src="images/ajax-loader.gif" alt="retrieving" id="login_spinner" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
@ -1,9 +0,0 @@
|
||||
require 'rake'
|
||||
require 'spec/rake/spectask'
|
||||
|
||||
desc "Run all tests with RCov"
|
||||
Spec::Rake::SpecTask.new('test_with_rcov') do |t|
|
||||
t.spec_files = FileList['spec/*_spec.rb']
|
||||
t.rcov = true
|
||||
t.rcov_opts = ['--exclude', '/Library']
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
{
|
||||
"vdcpool": {
|
||||
"vdc": [
|
||||
{
|
||||
"hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc0",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"hosts": "testhostvdc1n0",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc1",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
{
|
||||
"vdcpool": {
|
||||
"vdc": [
|
||||
{
|
||||
"hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc0",
|
||||
"id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"zonepool": {
|
||||
"zone": [
|
||||
{
|
||||
"onename": "oneadmin",
|
||||
"onepass": "opennebula",
|
||||
"endpoint": "http://localhost:2633/RPC2",
|
||||
"numbervdcs": 2,
|
||||
"name": "testzone0",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"onename": "testname",
|
||||
"onepass": "testpass",
|
||||
"endpoint": "http://remoteserver:2633/RPC2",
|
||||
"numbervdcs": 0,
|
||||
"name": "testzone1",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
{
|
||||
"zonepool": {
|
||||
"zone": [
|
||||
{
|
||||
"onename": "oneadmin",
|
||||
"onepass": "opennebula",
|
||||
"endpoint": "http://localhost:2633/RPC2",
|
||||
"numbervdcs": 2,
|
||||
"name": "testzone0",
|
||||
"id": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
{
|
||||
"vdc": {
|
||||
"hosts": "5,7,9",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc0",
|
||||
"id": 1
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
NAME=testvdc0
|
||||
ZONEID=1
|
||||
HOSTS=5,7,9
|
||||
VDCADMINNAME=adminname
|
||||
VDCADMINPASS=adminpass
|
@ -1,5 +0,0 @@
|
||||
NAME=testvdc1
|
||||
HOSTS=8
|
||||
ZONEID=1
|
||||
VDCADMINNAME=othername
|
||||
VDCADMINPASS=otherpass
|
@ -1,3 +0,0 @@
|
||||
NAME=testvdcnozone
|
||||
HOSTS=3,7
|
||||
ZONEID=5
|
@ -1,23 +0,0 @@
|
||||
{
|
||||
"zone": {
|
||||
"onename": "oneadmin",
|
||||
"onepass": "opennebula",
|
||||
"endpoint": "http://localhost:2633/RPC2",
|
||||
"name": "testzone0",
|
||||
"id": 1,
|
||||
"vdcs": [
|
||||
{
|
||||
"hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc0",
|
||||
"id": 1
|
||||
},
|
||||
{
|
||||
"hosts": "testhostvdc1n0",
|
||||
"zones_id": 1,
|
||||
"name": "testvdc1",
|
||||
"id": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
NAME=testzone0
|
||||
ENDPOINT=http://localhost:2633/RPC2
|
||||
ONENAME=oneadmin
|
||||
ONEPASS=opennebula
|
@ -1,4 +0,0 @@
|
||||
NAME=testzone1
|
||||
ENDPOINT=http://remoteserver:2633/RPC2
|
||||
ONENAME=testname
|
||||
ONEPASS=testpass
|
@ -1,133 +0,0 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# Load libraries
|
||||
require 'rubygems'
|
||||
require 'spec'
|
||||
require 'json'
|
||||
require File.dirname(__FILE__) + "/../../../Client/lib/OZonesClient.rb"
|
||||
|
||||
EXAMPLES_PATH = File.dirname(__FILE__) + "/../examples/"
|
||||
|
||||
describe 'OZones Pool' do
|
||||
before(:all) do
|
||||
@client_launched = true
|
||||
|
||||
begin
|
||||
@ozones_client = OZonesClient::Client.new("http://localhost:6121")
|
||||
rescue Exception => e
|
||||
@client_launched = false
|
||||
end
|
||||
|
||||
@client_launched.should == true
|
||||
|
||||
rc = @ozones_client.post_resource(
|
||||
"zone",EXAMPLES_PATH + '/zone/zone0.template')
|
||||
rc.class.should_not eql(OZonesClient::Error)
|
||||
|
||||
rc = @ozones_client.post_resource(
|
||||
"zone",EXAMPLES_PATH + '/zone/zone1.template')
|
||||
rc.class.should_not eql(OZonesClient::Error)
|
||||
|
||||
rc = @ozones_client.post_resource(
|
||||
"vdc",EXAMPLES_PATH + '/vdc/vdc0.template')
|
||||
rc.class.should_not eql(OZonesClient::Error)
|
||||
|
||||
rc = @ozones_client.post_resource(
|
||||
"vdc",EXAMPLES_PATH + '/vdc/vdc1.template')
|
||||
rc.class.should_not eql(OZonesClient::Error)
|
||||
|
||||
end
|
||||
|
||||
it "should be able to retrieve the zone pool" do
|
||||
zonepool = @ozones_client.get_pool("zone")
|
||||
zonepool.class.should eql(Net::HTTPOK)
|
||||
zonepool.body.should eql(
|
||||
File.read(EXAMPLES_PATH+'/pool/zonepool0.json'))
|
||||
end
|
||||
|
||||
it "should be able to retrieve the vdc pool" do
|
||||
vdcpool = @ozones_client.get_pool("vdc")
|
||||
vdcpool.class.should eql(Net::HTTPOK)
|
||||
vdcpool.body.should eql(
|
||||
File.read(EXAMPLES_PATH+'/pool/vdcpool0.json'))
|
||||
end
|
||||
|
||||
it "should be able to retrieve a particular zone" do
|
||||
zone0 = @ozones_client.get_resource("zone",1)
|
||||
zone0.class.should eql(Net::HTTPOK)
|
||||
zone0.body.should eql(
|
||||
File.read(EXAMPLES_PATH+'/zone/zone0.json'))
|
||||
end
|
||||
|
||||
it "should be able to retrieve a particular vdc" do
|
||||
vdc0 = @ozones_client.get_resource("vdc",1)
|
||||
vdc0.class.should eql(Net::HTTPOK)
|
||||
vdc0.body.should eql(
|
||||
File.read(EXAMPLES_PATH+'/vdc/vdc0.json'))
|
||||
end
|
||||
|
||||
it "should fail on zone recreation (with the same name)" do
|
||||
rc = @ozones_client.post_resource(
|
||||
"zone",EXAMPLES_PATH + '/zone/zone0.template')
|
||||
rc.class.should eql(OZonesClient::Error)
|
||||
end
|
||||
|
||||
it "should fail on vdc recreation (with the same name)" do
|
||||
rc = @ozones_client.post_resource(
|
||||
"vdc",EXAMPLES_PATH + '/vdc/vdc0.template')
|
||||
rc.class.should eql(OZonesClient::Error)
|
||||
end
|
||||
|
||||
it "should fail on vdc creation with no existing zone" do
|
||||
rc = @ozones_client.post_resource(
|
||||
"vdc",EXAMPLES_PATH +
|
||||
'/vdc/vdc2nozone.template')
|
||||
rc.class.should eql(OZonesClient::Error)
|
||||
end
|
||||
|
||||
it "should allow deleting a zone" do
|
||||
rc = @ozones_client.delete_resource("zone",2)
|
||||
rc.class.should eql(Net::HTTPOK)
|
||||
# Zone pool shouldn't account for the deleted zone
|
||||
zonepool = @ozones_client.get_pool("zone")
|
||||
zonepool.class.should eql(Net::HTTPOK)
|
||||
zonepool.body.should eql(
|
||||
File.read(EXAMPLES_PATH+
|
||||
'/pool/zonepool1deleted.json'))
|
||||
end
|
||||
|
||||
it "should allow deleting a vdc" do
|
||||
rc = @ozones_client.delete_resource("vdc",2)
|
||||
rc.class.should eql(Net::HTTPOK)
|
||||
# Zone pool shouldn't account for the deleted zone
|
||||
vdcpool = @ozones_client.get_pool("vdc")
|
||||
vdcpool.class.should eql(Net::HTTPOK)
|
||||
vdcpool.body.should eql(
|
||||
File.read(EXAMPLES_PATH+
|
||||
'/pool/vdcpool1deleted.json'))
|
||||
end
|
||||
|
||||
it "should fail on non existing zone deletion" do
|
||||
rc = @ozones_client.delete_resource("zone",5)
|
||||
rc.class.should eql(OZonesClient::Error)
|
||||
end
|
||||
|
||||
it "should fail on non existing vdc deletion" do
|
||||
rc = @ozones_client.delete_resource("vdc",5)
|
||||
rc.class.should eql(OZonesClient::Error)
|
||||
end
|
||||
end
|
@ -1,46 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
VAR_LOCATION="$PWD/var"
|
||||
OZONES_LOCATION="$PWD/../"
|
||||
|
||||
mkdir -p $VAR_LOCATION
|
||||
|
||||
if [ "$(ls -A $VAR_LOCATION)" ]; then
|
||||
echo "$VAR_LOCATION is not empty."
|
||||
exit -1
|
||||
fi
|
||||
|
||||
rm -rf coverage_server
|
||||
|
||||
rcov --exclude /Library --exclude /Users/tinova/.gem -o coverage_server `which rackup` -- $OZONES_LOCATION/config.ru -s thin -p 6121 -o localhost &> server.log &
|
||||
RCOVPID=$!
|
||||
sleep 5
|
||||
|
||||
rake test_with_rcov
|
||||
CODE=$?
|
||||
|
||||
kill $RCOVPID
|
||||
sleep 2s;
|
||||
|
||||
if [ $CODE != 0 ] ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
find $VAR_LOCATION -mindepth 1 -delete
|
57
src/ozones/test/etc/oned.conf.a
Normal file
57
src/ozones/test/etc/oned.conf.a
Normal file
@ -0,0 +1,57 @@
|
||||
HOST_MONITORING_INTERVAL = 600
|
||||
#HOST_PER_INTERVAL = 15
|
||||
|
||||
VM_POLLING_INTERVAL = 600
|
||||
#VM_PER_INTERVAL = 5
|
||||
|
||||
#VM_DIR=/srv/cloud/one/var
|
||||
|
||||
SCRIPTS_REMOTE_DIR=/var/tmp/one
|
||||
|
||||
PORT = 2666
|
||||
|
||||
DB = [ backend = "sqlite" ]
|
||||
|
||||
VNC_BASE_PORT = 5900
|
||||
|
||||
DEBUG_LEVEL = 3
|
||||
|
||||
NETWORK_SIZE = 254
|
||||
|
||||
MAC_PREFIX = "02:00"
|
||||
|
||||
DEFAULT_IMAGE_TYPE = "OS"
|
||||
DEFAULT_DEVICE_PREFIX = "hd"
|
||||
|
||||
|
||||
IM_MAD = [ name="im_dummy", executable="one_im_dummy"]
|
||||
|
||||
VM_MAD = [ name="vmm_dummy", executable="one_vmm_dummy", type="xml" ]
|
||||
|
||||
TM_MAD = [
|
||||
name = "tm_dummy",
|
||||
executable = "one_tm",
|
||||
arguments = "tm_dummy/tm_dummy.conf" ]
|
||||
|
||||
IMAGE_MAD = [
|
||||
executable = "one_image",
|
||||
arguments = "fs -t 15" ]
|
||||
|
||||
HM_MAD = [
|
||||
executable = "one_hm" ]
|
||||
|
||||
AUTH_MAD = [
|
||||
executable = "one_auth_mad",
|
||||
arguments = "--authn ssh,x509,ldap,server_cipher,server_x509"
|
||||
# arguments = "--authz quota --authn ssh,x509,ldap,server_cipher,server_x509"
|
||||
]
|
||||
|
||||
SESSION_EXPIRATION_TIME = 900
|
||||
|
||||
VM_RESTRICTED_ATTR = "CONTEXT/FILES"
|
||||
VM_RESTRICTED_ATTR = "DISK/SOURCE"
|
||||
VM_RESTRICTED_ATTR = "NIC/MAC"
|
||||
VM_RESTRICTED_ATTR = "NIC/VLAN_ID"
|
||||
VM_RESTRICTED_ATTR = "RANK"
|
||||
|
||||
IMAGE_RESTRICTED_ATTR = "SOURCE"
|
@ -1,30 +1,57 @@
|
||||
#*******************************************************************************
|
||||
# OpenNebula Configuration file
|
||||
#*******************************************************************************
|
||||
|
||||
# General
|
||||
|
||||
HOST_MONITORING_INTERVAL = 600
|
||||
#HOST_PER_INTERVAL = 15
|
||||
|
||||
VM_POLLING_INTERVAL = 600
|
||||
#VM_PER_INTERVAL = 5
|
||||
|
||||
#VM_DIR=/srv/cloud/one/var
|
||||
|
||||
SCRIPTS_REMOTE_DIR=/var/tmp/one
|
||||
PORT=2637
|
||||
|
||||
PORT = 2667
|
||||
|
||||
DB = [ backend = "sqlite" ]
|
||||
|
||||
VNC_BASE_PORT = 5900
|
||||
DEBUG_LEVEL=3
|
||||
|
||||
DEBUG_LEVEL = 3
|
||||
|
||||
NETWORK_SIZE = 254
|
||||
|
||||
MAC_PREFIX = "02:00"
|
||||
|
||||
DEFAULT_IMAGE_TYPE = "OS"
|
||||
DEFAULT_DEVICE_PREFIX = "hd"
|
||||
|
||||
# Dummy
|
||||
|
||||
IM_MAD = [ name="im_dummy", executable="one_im_dummy"]
|
||||
VM_MAD = [ name="vmm_dummy",executable="one_vmm_dummy", type="xml" ]
|
||||
TM_MAD = [ name="tm_dummy", executable="one_tm", arguments ="tm_dummy/tm_dummy.conf" ]
|
||||
|
||||
# Image
|
||||
IMAGE_MAD = [ executable = "one_image", arguments = "fs -t 15" ]
|
||||
VM_MAD = [ name="vmm_dummy", executable="one_vmm_dummy", type="xml" ]
|
||||
|
||||
# Hook
|
||||
HM_MAD = [ executable = "one_hm" ]
|
||||
TM_MAD = [
|
||||
name = "tm_dummy",
|
||||
executable = "one_tm",
|
||||
arguments = "tm_dummy/tm_dummy.conf" ]
|
||||
|
||||
IMAGE_MAD = [
|
||||
executable = "one_image",
|
||||
arguments = "fs -t 15" ]
|
||||
|
||||
HM_MAD = [
|
||||
executable = "one_hm" ]
|
||||
|
||||
AUTH_MAD = [
|
||||
executable = "one_auth_mad",
|
||||
arguments = "--authn ssh,x509,ldap,server_cipher,server_x509"
|
||||
# arguments = "--authz quota --authn ssh,x509,ldap,server_cipher,server_x509"
|
||||
]
|
||||
|
||||
SESSION_EXPIRATION_TIME = 900
|
||||
|
||||
VM_RESTRICTED_ATTR = "CONTEXT/FILES"
|
||||
VM_RESTRICTED_ATTR = "DISK/SOURCE"
|
||||
VM_RESTRICTED_ATTR = "NIC/MAC"
|
||||
VM_RESTRICTED_ATTR = "NIC/VLAN_ID"
|
||||
VM_RESTRICTED_ATTR = "RANK"
|
||||
|
||||
IMAGE_RESTRICTED_ATTR = "SOURCE"
|
||||
|
36
src/ozones/test/examples/pool/vdcpool0.json
Normal file
36
src/ozones/test/examples/pool/vdcpool0.json
Normal file
@ -0,0 +1,36 @@
|
||||
{
|
||||
"VDC_POOL": {
|
||||
"VDC": [
|
||||
{
|
||||
"ID": 1,
|
||||
"ACLS": "2,3,4,5,6,7",
|
||||
"HOSTS": "1,2,3",
|
||||
"NAME": "vdcA",
|
||||
"ZONES_ID": 1,
|
||||
"GROUP_ID": 100,
|
||||
"VDCADMINNAME": "vdcadminA",
|
||||
"VDCADMIN_ID": 2
|
||||
},
|
||||
{
|
||||
"ID": 2,
|
||||
"ACLS": "2,3,4,5",
|
||||
"HOSTS": "1",
|
||||
"NAME": "vdcB",
|
||||
"ZONES_ID": 2,
|
||||
"GROUP_ID": 100,
|
||||
"VDCADMINNAME": "vdcadminB",
|
||||
"VDCADMIN_ID": 2
|
||||
},
|
||||
{
|
||||
"ID": 3,
|
||||
"ACLS": "8,9,10,11",
|
||||
"HOSTS": "4",
|
||||
"NAME": "vdcC",
|
||||
"ZONES_ID": 1,
|
||||
"GROUP_ID": 101,
|
||||
"VDCADMINNAME": "vdcadminC",
|
||||
"VDCADMIN_ID": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
26
src/ozones/test/examples/pool/vdcpool_deleted.json
Normal file
26
src/ozones/test/examples/pool/vdcpool_deleted.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"VDC_POOL": {
|
||||
"VDC": [
|
||||
{
|
||||
"ID": 1,
|
||||
"ACLS": "2,3,4,5,6,7",
|
||||
"HOSTS": "1,2,3",
|
||||
"NAME": "vdcA",
|
||||
"ZONES_ID": 1,
|
||||
"GROUP_ID": 100,
|
||||
"VDCADMINNAME": "vdcadminA",
|
||||
"VDCADMIN_ID": 2
|
||||
},
|
||||
{
|
||||
"ID": 2,
|
||||
"ACLS": "2,3,4,5",
|
||||
"HOSTS": "1",
|
||||
"NAME": "vdcB",
|
||||
"ZONES_ID": 2,
|
||||
"GROUP_ID": 100,
|
||||
"VDCADMINNAME": "vdcadminB",
|
||||
"VDCADMIN_ID": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
26
src/ozones/test/examples/pool/zonepool0.json
Normal file
26
src/ozones/test/examples/pool/zonepool0.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"ZONE_POOL": {
|
||||
"ZONE": [
|
||||
{
|
||||
"ID": 1,
|
||||
"ENDPOINT": "http://localhost:2666/RPC2",
|
||||
"NUMBERVDCS": 0,
|
||||
"SUNSENDPOINT": "http://localhost:9869",
|
||||
"NAME": "zoneA",
|
||||
"SELFENDPOINT": null,
|
||||
"ONENAME": "oneadminA",
|
||||
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA=="
|
||||
},
|
||||
{
|
||||
"ID": 2,
|
||||
"ENDPOINT": "http://localhost:2667/RPC2",
|
||||
"NUMBERVDCS": 0,
|
||||
"SUNSENDPOINT": null,
|
||||
"NAME": "zoneB",
|
||||
"SELFENDPOINT": null,
|
||||
"ONENAME": "oneadminB",
|
||||
"ONEPASS": "8Si8vlo2P3qn5/SNxkMkDg=="
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
16
src/ozones/test/examples/pool/zonepool_deleted.json
Normal file
16
src/ozones/test/examples/pool/zonepool_deleted.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"ZONE_POOL": {
|
||||
"ZONE": [
|
||||
{
|
||||
"ID": 1,
|
||||
"ENDPOINT": "http://localhost:2666/RPC2",
|
||||
"NUMBERVDCS": 0,
|
||||
"SUNSENDPOINT": "http://localhost:9869",
|
||||
"NAME": "zoneA",
|
||||
"SELFENDPOINT": null,
|
||||
"ONENAME": "oneadminA",
|
||||
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA=="
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
12
src/ozones/test/examples/vdc/vdc0.json
Normal file
12
src/ozones/test/examples/vdc/vdc0.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"VDC": {
|
||||
"ID": 1,
|
||||
"ACLS": "2,3,4,5,6,7",
|
||||
"HOSTS": "1,2,3",
|
||||
"NAME": "vdcA",
|
||||
"ZONES_ID": 1,
|
||||
"GROUP_ID": 100,
|
||||
"VDCADMINNAME": "vdcadminA",
|
||||
"VDCADMIN_ID": 2
|
||||
}
|
||||
}
|
14
src/ozones/test/examples/zone/zone0.json
Normal file
14
src/ozones/test/examples/zone/zone0.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"ZONE": {
|
||||
"ID": 1,
|
||||
"ENDPOINT": "http://localhost:2666/RPC2",
|
||||
"SUNSENDPOINT": "http://localhost:9869",
|
||||
"VDCS": [
|
||||
|
||||
],
|
||||
"NAME": "zoneA",
|
||||
"SELFENDPOINT": null,
|
||||
"ONENAME": "oneadminA",
|
||||
"ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA=="
|
||||
}
|
||||
}
|
@ -29,89 +29,116 @@ require 'command_parser'
|
||||
require 'ozones_helper/zones_helper.rb'
|
||||
require 'ozones_helper/vdc_helper.rb'
|
||||
|
||||
TESTS_PATH = File.dirname(__FILE__)+"/../"
|
||||
|
||||
module OZones
|
||||
|
||||
describe "oZones server regarding VDCs" do
|
||||
before(:all) do
|
||||
@zonehelper =
|
||||
@zonehelper =
|
||||
ZonesHelper.new("zone", "ozonesadmin","ozonespassword")
|
||||
@vdchelper =
|
||||
VDCHelper.new("vdc", "ozonesadmin","ozonespassword")
|
||||
|
||||
@vdchelper =
|
||||
VDCHelper.new("vdc", "ozonesadmin","ozonespassword")
|
||||
|
||||
@clientA = OpenNebula::Client.new(File.read(
|
||||
File.dirname(__FILE__)+"/../etc/one_auth_a"),
|
||||
"http://localhost:2636/RPC2")
|
||||
|
||||
TESTS_PATH+"etc/one_auth_a"),
|
||||
"http://localhost:2666/RPC2")
|
||||
|
||||
@clientB = OpenNebula::Client.new(File.read(
|
||||
File.dirname(__FILE__)+"/../etc/one_auth_b"),
|
||||
"http://localhost:2637/RPC2")
|
||||
|
||||
TESTS_PATH+"etc/one_auth_b"),
|
||||
"http://localhost:2667/RPC2")
|
||||
|
||||
hostA=OpenNebula::Host.new(OpenNebula::Host.build_xml, @clientA)
|
||||
hostA.allocate("hostA1","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostA.allocate("hostA2","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostA.allocate("hostA3","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostA.allocate("hostA4","im_dummy","vmm_dummy","tm_dummy")
|
||||
|
||||
hostA.allocate("hostA1","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
hostA.allocate("hostA2","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
hostA.allocate("hostA3","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
hostA.allocate("hostA4","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
|
||||
hostB=OpenNebula::Host.new(OpenNebula::Host.build_xml, @clientB)
|
||||
hostB.allocate("hostB1","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostB.allocate("hostB2","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostB.allocate("hostB3","im_dummy","vmm_dummy","tm_dummy")
|
||||
hostB.allocate("hostB1","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
hostB.allocate("hostB2","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
hostB.allocate("hostB3","im_dummy","vmm_dummy","tm_dummy","dummy")
|
||||
end
|
||||
|
||||
|
||||
it "should be able to create a couple of zones" do
|
||||
@zonehelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneA.template")[0].should eql(0)
|
||||
@zonehelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneB.template")[0].should eql(0)
|
||||
end
|
||||
|
||||
it "should be able to create one vdc with the apropiate ONE resources" do
|
||||
@vdchelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/vdcA.template")[0].should eql(0)
|
||||
|
||||
rc = @zonehelper.create_resource(TESTS_PATH+"templates/zoneA.template")
|
||||
rc[0].should eql(0)
|
||||
rc = @zonehelper.create_resource(TESTS_PATH+"templates/zoneB.template")
|
||||
rc[0].should eql(0)
|
||||
end
|
||||
|
||||
it "should be able to create one vdc with apropiate ONE resources" do
|
||||
@vdchelper.create_resource(TESTS_PATH+"templates/vdcA.template",
|
||||
{:force => false})[0].should eql(0)
|
||||
|
||||
upool = OpenNebula::UserPool.new(@clientA)
|
||||
upool.info
|
||||
userExist=false
|
||||
upool.each{|user|
|
||||
upool.each{|user|
|
||||
if user['NAME'] == "vdcadminA"
|
||||
userExist=true
|
||||
end
|
||||
}
|
||||
|
||||
|
||||
userExist.should eql(true)
|
||||
|
||||
|
||||
gpool = OpenNebula::GroupPool.new(@clientA)
|
||||
gpool.info
|
||||
groupExist=false
|
||||
gpool.each{|group|
|
||||
gpool.each{|group|
|
||||
if group['NAME'] == "vdcA"
|
||||
groupExist=true
|
||||
end
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
groupExist.should eql(true)
|
||||
|
||||
|
||||
apool = OpenNebula::AclPool.new(@clientA)
|
||||
apool.info
|
||||
# TODO check ACLs
|
||||
end
|
||||
|
||||
it "should be able to create a couple of VDCs" do
|
||||
@vdchelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/vdcB.template")[0].should eql(0)
|
||||
@vdchelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/vdcC.template")[0].should eql(0)
|
||||
end
|
||||
|
||||
it "should fail when creating an existing VDC" do
|
||||
@vdchelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/vdcA.template")[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should fail when creating a VDC upon a non existing zone" do
|
||||
@vdchelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/vdc.no.zone.template")[0].should eql(-1)
|
||||
end
|
||||
|
||||
|
||||
it "should be able to create a couple of VDCs" do
|
||||
@vdchelper.create_resource(TESTS_PATH+"templates/vdcB.template",
|
||||
{:force => false})[0].should eql(0)
|
||||
@vdchelper.create_resource(TESTS_PATH+"templates/vdcC.template",
|
||||
{:force => false})[0].should eql(0)
|
||||
end
|
||||
|
||||
it "should fail when creating an existing VDC" do
|
||||
@vdchelper.create_resource(TESTS_PATH+"templates/vdcA.template",
|
||||
{:force => false})[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should fail when creating a VDC upon a non existing zone" do
|
||||
@vdchelper.create_resource(TESTS_PATH+"templates/vdc.no.zone.template",
|
||||
{:force => false})[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should be able to retrieve the vdc pool" do
|
||||
vdcpool = @vdchelper.list_pool({:json => true})
|
||||
vdcpool[0].should eql(0)
|
||||
vdcpool[1].should eql(File.read(TESTS_PATH+"examples/pool/vdcpool0.json"))
|
||||
end
|
||||
|
||||
it "should be able to retrieve a particular vdc" do
|
||||
vdc = @vdchelper.show_resource(1, {:json => true})
|
||||
vdc[0].should eql(0)
|
||||
vdc[1].should eql(File.read(TESTS_PATH+"examples/vdc/vdc0.json"))
|
||||
end
|
||||
|
||||
it "should allow deleting a vdc" do
|
||||
rc = @vdchelper.delete_resource(3, {})
|
||||
rc[0].should eql(0)
|
||||
rc = @vdchelper.list_pool({:json => true})
|
||||
rc[0].should eql(0)
|
||||
rc[1].should eql(File.read(TESTS_PATH+
|
||||
"examples/pool/vdcpool_deleted.json"))
|
||||
end
|
||||
|
||||
it "should fail on non-existing vdc deletion" do
|
||||
rc = @vdchelper.delete_resource(7, {})
|
||||
rc[0].should eql(-1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -28,36 +28,71 @@ $: << RUBY_LIB_LOCATION+"/cli"
|
||||
require 'command_parser'
|
||||
require 'ozones_helper/zones_helper.rb'
|
||||
|
||||
TESTS_PATH = File.dirname(__FILE__)+"/../"
|
||||
|
||||
module OZones
|
||||
|
||||
describe "oZones server regarding zones" do
|
||||
before(:all) do
|
||||
@helper = ZonesHelper.new("zone", "ozonesadmin","ozonespassword")
|
||||
@badhelper = ZonesHelper.new("zone", "wronguser","wrongpassword")
|
||||
@helper = ZonesHelper.new("zone", "ozonesadmin","ozonespassword")
|
||||
@badhelper = ZonesHelper.new("zone", "wronguser","wrongpassword")
|
||||
end
|
||||
|
||||
|
||||
it "should be able to create a couple of zones" do
|
||||
@helper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneA.template")[0].should eql(0)
|
||||
@helper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneB.template")[0].should eql(0)
|
||||
end
|
||||
|
||||
rc = @helper.create_resource(TESTS_PATH+"templates/zoneA.template")
|
||||
rc[0].should eql(0)
|
||||
|
||||
@helper.create_resource(TESTS_PATH+"templates/zoneB.template")
|
||||
rc[0].should eql(0)
|
||||
end
|
||||
|
||||
it "should fail with wrong zones templates" do
|
||||
@helper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zone.wrong.credentials.template")[0].should eql(-1)
|
||||
@helper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zone.wrong.endpoint.template")[0].should eql(-1)
|
||||
end
|
||||
|
||||
templ_path = "templates/zone.wrong.credentials.template"
|
||||
rc = @helper.create_resource(TESTS_PATH+templ_path)
|
||||
rc[0].should eql(-1)
|
||||
|
||||
templ_path = "templates/zone.wrong.endpoint.template"
|
||||
rc = @helper.create_resource(TESTS_PATH+templ_path)
|
||||
rc[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should fail when creating zones with existing name" do
|
||||
@helper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneA.template")[0].should eql(-1)
|
||||
end
|
||||
|
||||
rc = @helper.create_resource(TESTS_PATH+"templates/zoneA.template")
|
||||
rc[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should refuse unauthorized requests" do
|
||||
@badhelper.create_resource(File.dirname(__FILE__)+
|
||||
"/../templates/zoneA.template")[0].should eql(-1)
|
||||
end
|
||||
rc = @badhelper.create_resource(TESTS_PATH+
|
||||
"templates/zoneA.template")
|
||||
rc[0].should eql(-1)
|
||||
end
|
||||
|
||||
it "should be able to retrieve the zone pool" do
|
||||
zonepool = @helper.list_pool({:json => true})
|
||||
zonepool[0].should eql(0)
|
||||
zonepool[1].should eql(File.read(TESTS_PATH+
|
||||
"examples/pool/zonepool0.json"))
|
||||
end
|
||||
|
||||
it "should be able to retrieve a particular zone" do
|
||||
zone = @helper.show_resource(1,{:json => true})
|
||||
zone[0].should eql(0)
|
||||
zone[1].should eql(File.read(TESTS_PATH+"examples/zone/zone0.json"))
|
||||
end
|
||||
|
||||
it "should allow deleting a zone" do
|
||||
rc = @helper.delete_resource(2, {})
|
||||
rc[0].should eql(0)
|
||||
rc = @helper.list_pool({:json => true})
|
||||
rc[0].should eql(0)
|
||||
rc[1].should eql(File.read(TESTS_PATH+
|
||||
"examples/pool/zonepool_deleted.json"))
|
||||
end
|
||||
|
||||
it "should fail on non existing zone deletion" do
|
||||
rc = @helper.delete_resource(7, {})
|
||||
rc[0].should eql(-1)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,4 +2,4 @@ NAME=vdcC
|
||||
VDCADMINNAME=vdcadminC
|
||||
VDCADMINPASS=vdcpassC
|
||||
ZONEID=1
|
||||
HOSTS=3
|
||||
HOSTS=4
|
||||
|
@ -1,5 +1,5 @@
|
||||
NAME=zoneA
|
||||
ONENAME=oneadminA
|
||||
ONEPASS=opennebulaA
|
||||
ENDPOINT=http://localhost:2636/RPC2
|
||||
SUNSENDPOINT=http://localhost:9869
|
||||
ENDPOINT=http://localhost:2666/RPC2
|
||||
SUNSENDPOINT=http://localhost:9869
|
||||
|
@ -1,4 +1,4 @@
|
||||
NAME=zoneB
|
||||
ONENAME=oneadminB
|
||||
ONEPASS=opennebulaB
|
||||
ENDPOINT=http://localhost:2637/RPC2
|
||||
ENDPOINT=http://localhost:2667/RPC2
|
||||
|
@ -35,8 +35,7 @@ for j in `ls ./spec/*_spec.rb` ; do
|
||||
OZONES_AUTH=$PWD/etc/ozones_auth ONE_LOCATION=$ONE_LOCATION_A oneA/bin/ozones-server start
|
||||
|
||||
sleep 5
|
||||
|
||||
ONE_LOCATION=$ONE_LOCATION_A spec $j -f s
|
||||
ONE_LOCATION=$ONE_LOCATION_A rspec $j -f s
|
||||
CODE=$?
|
||||
|
||||
if [ $CODE != 0 ] ; then
|
||||
@ -52,18 +51,7 @@ for j in `ls ./spec/*_spec.rb` ; do
|
||||
done
|
||||
|
||||
if (($CODE == 0)); then
|
||||
# Terminate ONEs
|
||||
ONE_LOCATION=$ONE_LOCATION_A oneA/bin/one stop
|
||||
ONE_LOCATION=$ONE_LOCATION_B oneB/bin/one stop
|
||||
|
||||
# Stop oZones
|
||||
ONE_LOCATION=$ONE_LOCATION_A oneA/bin/ozones-server stop
|
||||
|
||||
# Delete directories
|
||||
rm -rf oneA
|
||||
rm -rf oneB
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
fi
|
@ -21,7 +21,7 @@ require 'OpenNebula'
|
||||
# This class provides support for launching and stopping a websockify proxy
|
||||
#
|
||||
class OpenNebulaVNC
|
||||
def initialize(config, opt={:json_errors => true})
|
||||
def initialize(config, logger, opt={:json_errors => true})
|
||||
@proxy_path = config[:vnc_proxy_path]
|
||||
@proxy_base_port = config[:vnc_proxy_base_port].to_i
|
||||
|
||||
@ -36,6 +36,7 @@ class OpenNebulaVNC
|
||||
end
|
||||
|
||||
@options = opt
|
||||
@logger = logger
|
||||
end
|
||||
|
||||
# Start a VNC proxy
|
||||
@ -71,7 +72,7 @@ class OpenNebulaVNC
|
||||
cmd ="#{@proxy_path} #{proxy_options} #{proxy_port} #{host}:#{vnc_port}"
|
||||
|
||||
begin
|
||||
$stderr.puts("Starting vnc proxy: #{cmd}")
|
||||
@logger.info { "Starting vnc proxy: #{cmd}" }
|
||||
pipe = IO.popen(cmd)
|
||||
rescue Exception => e
|
||||
return [500, OpenNebula::Error.new(e.message).to_json]
|
||||
|
@ -1,23 +0,0 @@
|
||||
#!/usr/bin/ruby
|
||||
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
$: << File.dirname(__FILE__)
|
||||
|
||||
require 'sunstone-server.rb'
|
||||
|
||||
run Sinatra::Application
|
@ -1,6 +1,9 @@
|
||||
# OpenNebula sever contact information
|
||||
:one_xmlrpc: http://localhost:2633/RPC2
|
||||
|
||||
# 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG
|
||||
:debug_level: 3
|
||||
|
||||
# Server Configuration
|
||||
:host: 127.0.0.1
|
||||
:port: 9869
|
||||
|
@ -14,6 +14,8 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'CloudServer'
|
||||
|
||||
require 'OpenNebulaJSON'
|
||||
include OpenNebulaJSON
|
||||
|
||||
@ -22,14 +24,15 @@ require 'OpenNebulaVNC'
|
||||
require 'OpenNebulaJSON/JSONUtils'
|
||||
include JSONUtils
|
||||
|
||||
class SunstoneServer
|
||||
class SunstoneServer < CloudServer
|
||||
# FLAG that will filter the elements retrieved from the Pools
|
||||
POOL_FILTER = Pool::INFO_ALL
|
||||
|
||||
# Secs to sleep between checks to see if image upload to repo is finished
|
||||
IMAGE_POLL_SLEEP_TIME = 5
|
||||
|
||||
def initialize(client)
|
||||
def initialize(client, config, logger)
|
||||
super(config, logger)
|
||||
@client = client
|
||||
end
|
||||
|
||||
@ -194,7 +197,8 @@ class SunstoneServer
|
||||
begin
|
||||
log = File.read(vm_log_file)
|
||||
rescue Exception => e
|
||||
return [200, "Log for VM #{id} not available"]
|
||||
msg = "Log for VM #{id} not available"
|
||||
return [200, {:vm_log => msg}.to_json]
|
||||
end
|
||||
|
||||
return [200, {:vm_log => log}.to_json]
|
||||
@ -210,7 +214,7 @@ class SunstoneServer
|
||||
return [404, resource.to_json]
|
||||
end
|
||||
|
||||
vnc_proxy = OpenNebulaVNC.new(config)
|
||||
vnc_proxy = OpenNebulaVNC.new(config, logger)
|
||||
return vnc_proxy.start(resource)
|
||||
end
|
||||
|
||||
@ -221,7 +225,8 @@ class SunstoneServer
|
||||
begin
|
||||
OpenNebulaVNC.stop(pipe)
|
||||
rescue Exception => e
|
||||
error = Error.new(e.message)
|
||||
logger.error {e.message}
|
||||
error = Error.new("Error stopping VNC. Please check server logs.")
|
||||
return [500, error.to_json]
|
||||
end
|
||||
|
||||
|
@ -134,10 +134,17 @@ div#login input#login_btn:hover {
|
||||
.error_message {
|
||||
display: none;
|
||||
position: relative;
|
||||
width:400px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
top: 80px;
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color:red;
|
||||
font-size:1.6em;
|
||||
font-size:1.0em;
|
||||
}
|
||||
|
||||
#login_spinner {
|
||||
left: 44px;
|
||||
position: relative;
|
||||
top: 2px;
|
||||
}
|
||||
|
||||
#label_remember {
|
||||
|
@ -24,14 +24,19 @@ function auth_error(req, error){
|
||||
|
||||
switch (status){
|
||||
case 401:
|
||||
$("#one_error").hide();
|
||||
$("#auth_error").fadeIn("slow");
|
||||
$("#error_box").text("Invalid username or password");
|
||||
break;
|
||||
case 500:
|
||||
$("#auth_error").hide();
|
||||
$("#one_error").fadeIn("slow");
|
||||
$("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs.");
|
||||
break;
|
||||
case 0:
|
||||
$("#error_box").text("No answer from server. Is it running?");
|
||||
break;
|
||||
default:
|
||||
$("#error_box").text("Unexpected error. Status "+status+". Check the server logs.");
|
||||
};
|
||||
$("#error_box").fadeIn("slow");
|
||||
$("#login_spinner").hide();
|
||||
}
|
||||
|
||||
function authenticate(){
|
||||
@ -39,6 +44,9 @@ function authenticate(){
|
||||
var password = $("#password").val();
|
||||
var remember = $("#check_remember").is(":checked");
|
||||
|
||||
$("#error_box").fadeOut("slow");
|
||||
$("#login_spinner").show();
|
||||
|
||||
OpenNebula.Auth.login({ data: {username: username
|
||||
, password: password}
|
||||
, remember: remember
|
||||
@ -61,4 +69,5 @@ $(document).ready(function(){
|
||||
};
|
||||
|
||||
$("input#username.box").focus();
|
||||
$("#login_spinner").hide();
|
||||
});
|
||||
|
@ -131,9 +131,11 @@ var user_actions = {
|
||||
"User.passwd" : {
|
||||
type: "multiple",
|
||||
call: OpenNebula.User.passwd,
|
||||
//nocallback
|
||||
callback: function(req,res){
|
||||
notifyMessage(tr("Change password successful"));
|
||||
},
|
||||
elements: userElements,
|
||||
error: onError
|
||||
error: onError,
|
||||
},
|
||||
"User.chgrp" : {
|
||||
type: "multiple",
|
||||
@ -492,6 +494,7 @@ function popUpCreateUserDialog(){
|
||||
|
||||
|
||||
function popUpUpdatePasswordDialog(){
|
||||
$('#new_password',$update_pw_dialog).val("");
|
||||
$update_pw_dialog.dialog('open');
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,9 @@ else
|
||||
end
|
||||
|
||||
SUNSTONE_AUTH = VAR_LOCATION + "/.one/sunstone_auth"
|
||||
SUNSTONE_LOG = LOG_LOCATION + "/sunstone.log"
|
||||
CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-server.conf"
|
||||
|
||||
PLUGIN_CONFIGURATION_FILE = ETC_LOCATION + "/sunstone-plugins.yaml"
|
||||
|
||||
SUNSTONE_ROOT_DIR = File.dirname(__FILE__)
|
||||
@ -54,27 +56,42 @@ require 'CloudAuth'
|
||||
require 'SunstoneServer'
|
||||
require 'SunstonePlugins'
|
||||
|
||||
|
||||
##############################################################################
|
||||
# Configuration
|
||||
##############################################################################
|
||||
|
||||
begin
|
||||
conf = YAML.load_file(CONFIGURATION_FILE)
|
||||
rescue Exception => e
|
||||
puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
STDERR.puts "Error parsing config file #{CONFIGURATION_FILE}: #{e.message}"
|
||||
exit 1
|
||||
end
|
||||
|
||||
##############################################################################
|
||||
# Sinatra Configuration
|
||||
##############################################################################
|
||||
use Rack::Session::Pool, :key => 'sunstone'
|
||||
conf[:debug_level] ||= 3
|
||||
|
||||
CloudServer.print_configuration(conf)
|
||||
|
||||
#Sinatra configuration
|
||||
|
||||
set :config, conf
|
||||
set :bind, settings.config[:host]
|
||||
set :port, settings.config[:port]
|
||||
|
||||
use Rack::Session::Pool, :key => 'sunstone'
|
||||
|
||||
# Enable logger
|
||||
|
||||
include CloudLogger
|
||||
enable_logging SUNSTONE_LOG, settings.config[:debug_level].to_i
|
||||
|
||||
begin
|
||||
ENV["ONE_CIPHER_AUTH"] = SUNSTONE_AUTH
|
||||
cloud_auth = CloudAuth.new(settings.config)
|
||||
rescue => e
|
||||
puts "Error initializing authentication system"
|
||||
puts e.message
|
||||
settings.logger.error {
|
||||
"Error initializing authentication system" }
|
||||
settings.logger.error { e.message }
|
||||
exit -1
|
||||
end
|
||||
|
||||
@ -93,10 +110,12 @@ helpers do
|
||||
settings.cloud_auth.update_userpool_cache
|
||||
result = settings.cloud_auth.auth(request.env, params)
|
||||
rescue Exception => e
|
||||
error 500, e.message
|
||||
error 500, ""
|
||||
logger.error { e.message }
|
||||
end
|
||||
|
||||
if result.nil?
|
||||
logger.info { "Unauthorized login attempt" }
|
||||
return [401, ""]
|
||||
else
|
||||
client = settings.cloud_auth.client(result)
|
||||
@ -105,7 +124,7 @@ helpers do
|
||||
user = OpenNebula::User.new_with_id(user_id, client)
|
||||
rc = user.info
|
||||
if OpenNebula.is_error?(rc)
|
||||
# Add a log message
|
||||
logger.error { rc.message }
|
||||
return [500, ""]
|
||||
end
|
||||
|
||||
@ -157,7 +176,9 @@ before do
|
||||
halt 401 unless authorized?
|
||||
|
||||
@SunstoneServer = SunstoneServer.new(
|
||||
settings.cloud_auth.client(session[:user]))
|
||||
settings.cloud_auth.client(session[:user]),
|
||||
settings.config,
|
||||
settings.logger)
|
||||
end
|
||||
end
|
||||
|
||||
@ -244,7 +265,10 @@ end
|
||||
post '/config' do
|
||||
begin
|
||||
body = JSON.parse(request.body.read)
|
||||
rescue
|
||||
rescue Exception => e
|
||||
msg = "Error parsing configuration JSON"
|
||||
logger.error { msg }
|
||||
logger.error { e.message }
|
||||
[500, OpenNebula::Error.new(msg).to_json]
|
||||
end
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>OpenNebula Sunstone Login</title>
|
||||
<link rel="stylesheet" type="text/css" href="css/login.css" />
|
||||
<link rel="stylesheet" type="text/css" href="vendor/jQueryUI/jquery-ui-1.8.16.custom.css" />
|
||||
|
||||
<!-- Vendor Libraries -->
|
||||
<script type="text/javascript" src="vendor/jQuery/jquery-1.7.1.min.js"></script>
|
||||
@ -25,11 +26,7 @@
|
||||
<div id="logo_sunstone">
|
||||
</div>
|
||||
|
||||
<div id="auth_error" class="error_message">
|
||||
Invalid username or password
|
||||
</div>
|
||||
<div id="one_error" class="error_message">
|
||||
OpenNebula is not running
|
||||
<div id="error_box" class="error_message ui-state-error ui-corner-all">
|
||||
</div>
|
||||
|
||||
<form id="login_form">
|
||||
@ -43,6 +40,7 @@
|
||||
<input type="checkbox" id="check_remember" />
|
||||
<label id="label_remember" for="check_remember">Remember me</label>
|
||||
<input type="submit" id="login_btn" value="" />
|
||||
<img src="images/ajax-loader.gif" alt="retrieving" id="login_spinner" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user