mirror of
https://github.com/OpenNebula/one.git
synced 2025-01-11 05:17:41 +03:00
feature #1288: Remove previous quota drivers
This commit is contained in:
parent
981db30338
commit
e793ca89e1
@ -246,7 +246,6 @@ VAR_DIRS="$VAR_LOCATION/remotes \
|
||||
$VAR_LOCATION/remotes/auth/ldap \
|
||||
$VAR_LOCATION/remotes/auth/server_x509 \
|
||||
$VAR_LOCATION/remotes/auth/server_cipher \
|
||||
$VAR_LOCATION/remotes/auth/quota \
|
||||
$VAR_LOCATION/remotes/auth/dummy"
|
||||
|
||||
SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \
|
||||
@ -384,7 +383,6 @@ INSTALL_FILES=(
|
||||
AUTH_SERVER_CIPHER_FILES:$VAR_LOCATION/remotes/auth/server_cipher
|
||||
AUTH_DUMMY_FILES:$VAR_LOCATION/remotes/auth/dummy
|
||||
AUTH_PLAIN_FILES:$VAR_LOCATION/remotes/auth/plain
|
||||
AUTH_QUOTA_FILES:$VAR_LOCATION/remotes/auth/quota
|
||||
VMM_EXEC_KVM_SCRIPTS:$VAR_LOCATION/remotes/vmm/kvm
|
||||
VMM_EXEC_XEN_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen
|
||||
VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
|
||||
@ -574,7 +572,6 @@ BIN_FILES="src/nebula/oned \
|
||||
src/cli/onedatastore \
|
||||
src/cli/onecluster \
|
||||
src/onedb/onedb \
|
||||
src/authm_mad/remotes/quota/onequota \
|
||||
src/mad/utils/tty_expect \
|
||||
share/scripts/one"
|
||||
|
||||
@ -601,7 +598,6 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
|
||||
src/mad/ruby/Ganglia.rb \
|
||||
src/oca/ruby/OpenNebula.rb \
|
||||
src/authm_mad/remotes/ssh/ssh_auth.rb \
|
||||
src/authm_mad/remotes/quota/quota.rb \
|
||||
src/authm_mad/remotes/server_x509/server_x509_auth.rb \
|
||||
src/authm_mad/remotes/server_cipher/server_cipher_auth.rb \
|
||||
src/authm_mad/remotes/ldap/ldap_auth.rb \
|
||||
@ -732,8 +728,6 @@ AUTH_DUMMY_FILES="src/authm_mad/remotes/dummy/authenticate"
|
||||
|
||||
AUTH_PLAIN_FILES="src/authm_mad/remotes/plain/authenticate"
|
||||
|
||||
AUTH_QUOTA_FILES="src/authm_mad/remotes/quota/authorize"
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Virtual Network Manager drivers to be installed under $REMOTES_LOCATION/vnm
|
||||
#-------------------------------------------------------------------------------
|
||||
@ -942,7 +936,6 @@ HM_ETC_FILES="src/hm_mad/hmrc"
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
AUTH_ETC_FILES="src/authm_mad/remotes/server_x509/server_x509_auth.conf \
|
||||
src/authm_mad/remotes/quota/quota.conf \
|
||||
src/authm_mad/remotes/ldap/ldap_auth.conf \
|
||||
src/authm_mad/remotes/x509/x509_auth.conf"
|
||||
|
||||
@ -1115,7 +1108,6 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
|
||||
src/cli/one_helper/oneimage_helper.rb \
|
||||
src/cli/one_helper/onetemplate_helper.rb \
|
||||
src/cli/one_helper/oneuser_helper.rb \
|
||||
src/cli/one_helper/onequota_helper.rb \
|
||||
src/cli/one_helper/onevm_helper.rb \
|
||||
src/cli/one_helper/onevnet_helper.rb \
|
||||
src/cli/one_helper/oneacl_helper.rb \
|
||||
|
@ -414,22 +414,20 @@ HM_MAD = [
|
||||
# valid. During this time, the driver is not used. Use 0 to disable session
|
||||
# caching
|
||||
#
|
||||
# ENABLE_OTHER_PERMISSIONS: Whether or not to enable the permissions for
|
||||
# 'other'. Users in the oneadmin group will still be able to change
|
||||
# these permissions. Values: YES or NO
|
||||
# ENABLE_OTHER_PERMISSIONS: Whether or not users can set the permissions for
|
||||
# 'other', so publishing or sharing resources with others. Users in the oneadmin
|
||||
# group will still be able to change these permissions. Values: YES or NO.
|
||||
#*******************************************************************************
|
||||
|
||||
AUTH_MAD = [
|
||||
executable = "one_auth_mad",
|
||||
authn = "ssh,x509,ldap,server_cipher,server_x509"
|
||||
# , authz = "quota"
|
||||
]
|
||||
|
||||
SESSION_EXPIRATION_TIME = 900
|
||||
|
||||
#ENABLE_OTHER_PERMISSIONS = "YES"
|
||||
|
||||
|
||||
#*******************************************************************************
|
||||
# Restricted Attributes Configuration
|
||||
#*******************************************************************************
|
||||
|
@ -1,69 +0,0 @@
|
||||
#!/usr/bin/env 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
ETC_LOCATION="/etc/one/"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
ETC_LOCATION=ONE_LOCATION+"/etc/"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
require 'scripts_common'
|
||||
require 'OpenNebula'
|
||||
require 'quota'
|
||||
|
||||
user_id = ARGV.shift
|
||||
|
||||
overall_evalutation = ARGV.pop
|
||||
exit -1 if overall_evalutation.to_i == 0
|
||||
|
||||
quota = Quota.new
|
||||
|
||||
#q = {
|
||||
# :cpu => 10,
|
||||
# :memory => 2048,
|
||||
# :storage => 100000,
|
||||
# :num_vms => 5
|
||||
#}
|
||||
#
|
||||
#quota.set(1, q)
|
||||
#OpenNebula.log_debug("quotas: #{quota.get(1)}")
|
||||
|
||||
ARGV.each {|request|
|
||||
obj, template_or_id, op, owner, acl_eval = request.split(':')
|
||||
|
||||
if ( obj == "TEMPLATE" && op == "USE" && ARGV.size == 1 )
|
||||
rc = false
|
||||
else
|
||||
rc = quota.authorize(user_id, request)
|
||||
end
|
||||
|
||||
if rc
|
||||
OpenNebula.error_message rc
|
||||
exit -1
|
||||
end
|
||||
}
|
||||
|
||||
#OpenNebula.log_debug("AUTHORIZE ARGS: #{ARGV.join(' ')}")
|
||||
|
||||
exit 0
|
@ -1,189 +0,0 @@
|
||||
#!/usr/bin/env 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'command_parser'
|
||||
require 'cli_helper'
|
||||
require 'one_helper'
|
||||
require 'quota'
|
||||
|
||||
require 'pp'
|
||||
|
||||
QUOTA_KEYS = Quota::DB_QUOTA_SCHEMA.keys
|
||||
|
||||
def show_table(values, usage=nil)
|
||||
size = usage ? 12 : 8
|
||||
|
||||
values.sort!{|v1, v2| v1[:UID]<=>v2[:UID] }
|
||||
|
||||
table=CLIHelper::ShowTable.new(nil, self) do
|
||||
column :UID, "ONE identifier for the User", :size=>4 do |d|
|
||||
d[:UID]
|
||||
end
|
||||
|
||||
QUOTA_KEYS.each { |key|
|
||||
column key, "#{key} quota", :size=>size do |d|
|
||||
if usage
|
||||
"#{usage[key].to_i}/#{d[key].to_i}"
|
||||
else
|
||||
"#{d[key].to_i}"
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
default :UID, *QUOTA_KEYS
|
||||
end
|
||||
|
||||
table.show(values)
|
||||
end
|
||||
|
||||
cmd=CommandParser::CmdParser.new(ARGV) do
|
||||
usage "`onequota` <command> [<args>] [<options>]"
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
quota = Quota.new
|
||||
|
||||
########################################################################
|
||||
# Global Options
|
||||
########################################################################
|
||||
set :option, CommandParser::OPTIONS
|
||||
|
||||
########################################################################
|
||||
# Argument Formats
|
||||
########################################################################
|
||||
quota_list_desc = <<-EOT.unindent
|
||||
List of quota keys, comma separated.
|
||||
Available quotas: #{QUOTA_KEYS.join(', ')}
|
||||
EOT
|
||||
|
||||
set :format, :quota_list, quota_list_desc do |arg|
|
||||
arg_list = arg.split(',')
|
||||
|
||||
rc = nil
|
||||
arg_list.collect! do |elem|
|
||||
sym = elem.upcase.to_sym
|
||||
if !QUOTA_KEYS.include?(sym)
|
||||
rc = -1, "#{elem} is not a valid quota"
|
||||
break
|
||||
end
|
||||
sym
|
||||
end
|
||||
|
||||
rc ? rc : [0, arg_list]
|
||||
end
|
||||
|
||||
set :format, :value_list, "List of quota values, comma separated." do |arg|
|
||||
arg_list = arg.split(',')
|
||||
arg_list.map! {|a| a.to_i }
|
||||
[0, arg_list]
|
||||
end
|
||||
|
||||
set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg|
|
||||
OpenNebulaHelper.rname_to_id(arg, "USER")
|
||||
end
|
||||
|
||||
########################################################################
|
||||
# Commands
|
||||
########################################################################
|
||||
set_desc = <<-EOT.unindent
|
||||
Set a quota for a given user.
|
||||
Examples:
|
||||
onequota set 3 cpu 12
|
||||
onequota set 4 cpu,memory,storage 8,4096,10000
|
||||
EOT
|
||||
|
||||
command :set, set_desc, :userid, :quota_list, :value_list do
|
||||
user_id, keys, values = args
|
||||
|
||||
if keys.length != values.length
|
||||
exit_with_code -1, "The number of keys and values does not match"
|
||||
end
|
||||
|
||||
values_hash = Hash.new
|
||||
keys.each_with_index { |k,i|
|
||||
values_hash[k] = values[i]
|
||||
}
|
||||
|
||||
quota.set_quota(user_id, values_hash)
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
########################################################################
|
||||
unset_desc = <<-EOT.unindent
|
||||
Unset a quota for a given user.
|
||||
Examples:
|
||||
onequota unset 3 cpu
|
||||
onequota unset 4 cpu,memory,storage
|
||||
EOT
|
||||
|
||||
command :unset, unset_desc, :userid, :quota_list do
|
||||
user_id, keys = args
|
||||
|
||||
values_hash = Hash.new
|
||||
keys.each_with_index { |k,i|
|
||||
values_hash[k] = 0
|
||||
}
|
||||
|
||||
quota.set_quota(user_id, values_hash)
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
########################################################################
|
||||
delete_desc = "Delete the defined quotas for the given user"
|
||||
|
||||
command :delete, delete_desc, :userid do
|
||||
quota.delete_quota(args[0])
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
########################################################################
|
||||
show_desc = "Show the user's quota and usage. (usage/quota)"
|
||||
|
||||
FORCE={
|
||||
:name => "force",
|
||||
:short => "-f",
|
||||
:large => "--force",
|
||||
:description => "Force the usage calculation instead of using the cache"
|
||||
}
|
||||
|
||||
command :show, show_desc, :userid, :options=>[FORCE] do
|
||||
user_usage = quota.get_usage(args[0],nil,options[:force])
|
||||
user_quota = quota.get_quota(args[0])
|
||||
|
||||
show_table([user_quota], user_usage)
|
||||
exit_with_code 0
|
||||
end
|
||||
|
||||
########################################################################
|
||||
list_desc = "List the defined quotas for all the users"
|
||||
|
||||
command :list, list_desc do
|
||||
show_table(quota.get_quota)
|
||||
exit_with_code 0
|
||||
end
|
||||
end
|
@ -1,29 +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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
# Database URI
|
||||
#:db: sqlite:///var/one/onequota.db
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Default quotas, these apply to all users. Leave empty to disable quota for
|
||||
# a given metric.
|
||||
#-------------------------------------------------------------------------------
|
||||
:defaults:
|
||||
:CPU:
|
||||
:MEMORY:
|
||||
:NUM_VMS:
|
||||
:STORAGE:
|
||||
|
@ -1,374 +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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'sequel'
|
||||
require 'base64'
|
||||
require 'yaml'
|
||||
require 'uri'
|
||||
require 'net/http'
|
||||
|
||||
class Quota
|
||||
###########################################################################
|
||||
# Constants with paths to relevant files and defaults
|
||||
###########################################################################
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
VAR_LOCATION = "/var/lib/one"
|
||||
ETC_LOCATION = "/etc/one"
|
||||
else
|
||||
VAR_LOCATION = ONE_LOCATION + "/var"
|
||||
ETC_LOCATION = ONE_LOCATION + "/etc"
|
||||
end
|
||||
|
||||
CONF_FILE = ETC_LOCATION + "/auth/quota.conf"
|
||||
|
||||
CONF = {
|
||||
:db => "sqlite://#{VAR_LOCATION}/onequota.db",
|
||||
:defaults => {
|
||||
:CPU => nil,
|
||||
:MEMORY => nil,
|
||||
:NUM_VMS => nil,
|
||||
:STORAGE => nil
|
||||
}
|
||||
}
|
||||
|
||||
###########################################################################
|
||||
# Schema for the USAGE and QUOTA tables
|
||||
###########################################################################
|
||||
DB_QUOTA_SCHEMA = {
|
||||
:CPU => Float,
|
||||
:MEMORY => Integer,
|
||||
:NUM_VMS => Integer,
|
||||
:STORAGE => Integer
|
||||
}
|
||||
|
||||
QUOTA_TABLE = :quotas
|
||||
USAGE_TABLE = :usage
|
||||
|
||||
###########################################################################
|
||||
# Usage params to calculate each quota
|
||||
###########################################################################
|
||||
VM_USAGE = {
|
||||
:CPU => {
|
||||
:proc_info => lambda {|template| template['CPU']},
|
||||
:xpath => 'TEMPLATE/CPU'
|
||||
},
|
||||
:MEMORY => {
|
||||
:proc_info => lambda {|template| template['MEMORY']},
|
||||
:xpath => 'TEMPLATE/MEMORY'
|
||||
},
|
||||
:NUM_VMS => {
|
||||
:proc_info => lambda {|template| 1 },
|
||||
:xpath => 'ID',
|
||||
:count => true
|
||||
}
|
||||
}
|
||||
|
||||
IMAGE_USAGE = {
|
||||
:STORAGE => {
|
||||
:proc_info => lambda {|template|
|
||||
if template['TYPE'] == 'DATABLOCK'
|
||||
template['SIZE'].to_i
|
||||
elsif template['PATH']
|
||||
uri = URI.parse(template['PATH'])
|
||||
size = if uri.scheme.nil?
|
||||
File.size(template['PATH'])
|
||||
else
|
||||
Net::HTTP.start(uri.host,uri.port) { |http|
|
||||
http.head(uri.path)
|
||||
}.content_length
|
||||
end
|
||||
(size.to_f / 2**20).round
|
||||
elsif template['SAVED_VM_ID']
|
||||
vm_id = template['SAVED_VM_ID'].to_i
|
||||
disk_id = template['SAVED_DISK_ID'].to_i
|
||||
|
||||
client = OpenNebula::Client.new
|
||||
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, client)
|
||||
vm.info
|
||||
|
||||
im_id = vm["DISK[DISK_ID=#{disk_id}]/IMAGE_ID"].to_i
|
||||
|
||||
im = OpenNebula::Image.new_with_id(im_id, client)
|
||||
im.info
|
||||
|
||||
im['SIZE'].to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
},
|
||||
:xpath => 'SIZE'
|
||||
}
|
||||
}
|
||||
|
||||
RESOURCES = ["VM", "IMAGE"]
|
||||
|
||||
###########################################################################
|
||||
# DB handling
|
||||
###########################################################################
|
||||
def initialize
|
||||
conf = YAML.load_file(CONF_FILE)
|
||||
@conf=CONF.merge(conf) {|key,h1,h2|
|
||||
if h1.instance_of?(Hash) && h2.instance_of?(Hash)
|
||||
h1.merge(h2)
|
||||
else
|
||||
if h2
|
||||
h2
|
||||
else
|
||||
h1
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
@client = OpenNebula::Client.new
|
||||
|
||||
@db=Sequel.connect(@conf[:db])
|
||||
|
||||
create_table(QUOTA_TABLE)
|
||||
create_table(USAGE_TABLE)
|
||||
end
|
||||
|
||||
# Creates database quota table if it does not exist
|
||||
def create_table(table)
|
||||
@db.create_table?(table) do
|
||||
Integer :UID
|
||||
|
||||
DB_QUOTA_SCHEMA.each { |key,value|
|
||||
column key, value
|
||||
}
|
||||
|
||||
primary_key :UID
|
||||
index :UID
|
||||
end
|
||||
end
|
||||
|
||||
# Adds new user limits
|
||||
def set(table, uid, quota={})
|
||||
data=quota.delete_if{|key,value| !DB_QUOTA_SCHEMA.keys.include?(key)}
|
||||
|
||||
quotas=@db[table].filter(:UID => uid)
|
||||
|
||||
if quotas.first
|
||||
quotas.update(data)
|
||||
else
|
||||
@db[table].insert(data.merge!(:UID => uid))
|
||||
end
|
||||
end
|
||||
|
||||
# Gets user limits
|
||||
def get(table, uid=nil)
|
||||
if uid
|
||||
@db[table].filter(:UID => uid).first
|
||||
else
|
||||
@db[table].all
|
||||
end
|
||||
end
|
||||
|
||||
# Delete user limits
|
||||
def delete(table, uid)
|
||||
quotas=@db[table].filter(:UID => uid)
|
||||
|
||||
if quotas.first
|
||||
quotas.delete
|
||||
end
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Quota Client
|
||||
###########################################################################
|
||||
def set_quota(uid, quota={})
|
||||
set(QUOTA_TABLE, uid, quota)
|
||||
end
|
||||
|
||||
# Retrieves quota information for a given user
|
||||
#
|
||||
# @param [Integer, nil] uid the user id from which get the quota
|
||||
# information, if nil will retrieve the quotas for all users.
|
||||
# @return [Hash] Hash containing the quota information and the user id
|
||||
#
|
||||
# {
|
||||
# :uid => 4,
|
||||
# :cpu => 8,
|
||||
# :memory => 8064,
|
||||
# :num_vms => 4,
|
||||
# :storage => 1240019
|
||||
# }
|
||||
def get_quota(uid=nil)
|
||||
limit = get(QUOTA_TABLE, uid)
|
||||
limit ? limit : @conf[:defaults].merge!(:UID => uid)
|
||||
end
|
||||
|
||||
def delete_quota(uid)
|
||||
delete(QUOTA_TABLE, uid)
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Authorization
|
||||
###########################################################################
|
||||
def authorize(user_id, request)
|
||||
obj, template_or_id, op, owner, acl_eval = request.split(':')
|
||||
|
||||
if acl_eval.to_i == 0
|
||||
return "ACL evaluation denied"
|
||||
end
|
||||
|
||||
# Check if this op needs to check the quota
|
||||
return false unless with_quota?(obj, op)
|
||||
|
||||
template = ""
|
||||
|
||||
if ( obj == "TEMPLATE" )
|
||||
obj = "VM"
|
||||
|
||||
vm_template = OpenNebula::Template.new_with_id(template_or_id, @client)
|
||||
vm_template.info
|
||||
|
||||
vm_template.each("TEMPLATE") { |xml_elem|
|
||||
template = xml_elem.to_xml
|
||||
}
|
||||
else
|
||||
template = Base64::decode64(template_or_id)
|
||||
end
|
||||
|
||||
check_quotas(user_id.to_i, obj, template)
|
||||
end
|
||||
|
||||
def check_quotas(user_id, obj, template)
|
||||
info = get_resources(obj, template)
|
||||
total = get_usage(user_id, obj, true)
|
||||
quota = get_quota(user_id)
|
||||
|
||||
msg = ""
|
||||
separator = ""
|
||||
info.each { |qname, quota_requested|
|
||||
unless quota[qname] || quota[qname]==0
|
||||
next
|
||||
end
|
||||
|
||||
type = DB_QUOTA_SCHEMA[qname].name.to_sym
|
||||
|
||||
used = send(type, total[qname])
|
||||
request = send(type, quota_requested)
|
||||
limit = send(type, quota[qname])
|
||||
spent = used + request
|
||||
|
||||
if spent > limit
|
||||
msg << separator
|
||||
msg << " #{qname.to_s.upcase} quota exceeded "
|
||||
msg << "(Quota: #{limit}, "
|
||||
msg << "Used: #{used}, "
|
||||
msg << "Requested: #{request})"
|
||||
|
||||
separator = ";"
|
||||
end
|
||||
}
|
||||
|
||||
if msg==""
|
||||
return false
|
||||
else
|
||||
return msg.strip
|
||||
end
|
||||
end
|
||||
|
||||
def with_quota?(obj, op)
|
||||
return (obj == "VM" && op == "CREATE") ||
|
||||
(obj == "IMAGE" && op == "CREATE") ||
|
||||
(obj == "TEMPLATE" && op == "USE")
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Usage
|
||||
###########################################################################
|
||||
# Retrieves usage information for a given user
|
||||
#
|
||||
# @param [Integer] uid the user id from which get the usage information.
|
||||
# @param ["VM", "IMAGE"] resource kind of resource. If nil will return
|
||||
# the usage for all kinds of resources
|
||||
# @param [true, false] force If true will force the usage calculation
|
||||
# instead of retrieving it from the cache
|
||||
# @return [Hash] Hash containing the usage information and the user id
|
||||
#
|
||||
# {
|
||||
# :uid => 4,
|
||||
# :cpu => 8,
|
||||
# :memory => 8064,
|
||||
# :num_vms => 4,
|
||||
# :storage => 1240019
|
||||
# }
|
||||
def get_usage(user_id, resource=nil, force=false)
|
||||
if force
|
||||
if RESOURCES.include?(resource)
|
||||
resources = [resource]
|
||||
else
|
||||
resources = RESOURCES
|
||||
end
|
||||
|
||||
usage = Hash.new
|
||||
|
||||
resources.each{ |res|
|
||||
pool = get_pool(res, user_id)
|
||||
base_xpath = "/#{res}_POOL/#{resource}"
|
||||
Quota.const_get("#{res}_USAGE".to_sym).each { |key, params|
|
||||
usage[key] ||= 0
|
||||
pool.each_xpath("#{base_xpath}/#{params[:xpath]}") { |elem|
|
||||
if elem
|
||||
if params[:count]
|
||||
usage[key] += 1
|
||||
else
|
||||
usage[key] += send(DB_QUOTA_SCHEMA[key].name.to_sym, elem)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
set(USAGE_TABLE, user_id, usage) unless usage.empty?
|
||||
usage.merge!(:UID => user_id)
|
||||
}
|
||||
else
|
||||
usage = get(USAGE_TABLE, user_id)
|
||||
usage ||= {:UID => user_id}
|
||||
end
|
||||
|
||||
usage
|
||||
end
|
||||
|
||||
# Retrieve the useful information of the template for the specified
|
||||
# kind of resource
|
||||
def get_resources(resource, xml_template)
|
||||
template = OpenNebula::XMLElement.new
|
||||
template.initialize_xml(xml_template, 'TEMPLATE')
|
||||
|
||||
info = Hash.new
|
||||
|
||||
self.class.const_get("#{resource}_USAGE").each { |key, params|
|
||||
info[key] = params[:proc_info].call(template).to_i
|
||||
}
|
||||
|
||||
info
|
||||
end
|
||||
|
||||
# Returns a an Array than contains the elements of the resource Pool
|
||||
def get_pool(resource, user_id)
|
||||
pool = case resource
|
||||
when "VM" then OpenNebula::VirtualMachinePool.new(@client, user_id)
|
||||
when "IMAGE" then OpenNebula::ImagePool.new(@client, user_id)
|
||||
end
|
||||
|
||||
rc = pool.info
|
||||
return pool
|
||||
end
|
||||
end
|
@ -1,26 +0,0 @@
|
||||
<IMAGE_POOL>
|
||||
<% images.each do |id,image| %>
|
||||
<IMAGE>
|
||||
<ID><%= id %></ID>
|
||||
<UID><%= image[:uid] ? image[:uid] : 0 %></UID>
|
||||
<GID><%= image[:gid] ? image[:gid] : 0 %></GID>
|
||||
<UNAME><%= image[:uname] ? image[:uname] : 'oneadmin' %></UNAME>
|
||||
<GNAME><%= image[:gname] ? image[:gname] : 'oneadmin' %></GNAME>
|
||||
<NAME><%= image[:name] ? image[:name] : 'ttylinux' %></NAME>
|
||||
<TYPE><%= image[:type] ? image[:type] : 0 %></TYPE>
|
||||
<PUBLIC><%= image[:pub] ? image[:pub] : 0 %></PUBLIC>
|
||||
<PERSISTENT><%= image[:persistent] ? image[:persistent] : 0 %></PERSISTENT>
|
||||
<REGTIME>1314875019</REGTIME>
|
||||
<SOURCE><%= image[:source] ? image[:source] : '/etc/hosts' %></SOURCE>
|
||||
<STATE><%= image[:state] ? image[:state] : 1 %></STATE>
|
||||
<SIZE><%= image[:size] ? image[:size] : 100 %></SIZE>
|
||||
<RUNNING_VMS>0</RUNNING_VMS>
|
||||
<TEMPLATE>
|
||||
<DEV_PREFIX><![CDATA[hd]]></DEV_PREFIX>
|
||||
<NAME><![CDATA[PEPE]]></NAME>
|
||||
<PATH><![CDATA[/etc/hosts]]></PATH>
|
||||
<TYPE><![CDATA[OS]]></TYPE>
|
||||
</TEMPLATE>
|
||||
</IMAGE>
|
||||
<% end %>
|
||||
</IMAGE_POOL>
|
46
src/authm_mad/remotes/quota/test/fixtures/vm.xml
vendored
46
src/authm_mad/remotes/quota/test/fixtures/vm.xml
vendored
@ -1,46 +0,0 @@
|
||||
<VM>
|
||||
<ID><%= id %></ID>
|
||||
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
|
||||
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
|
||||
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
|
||||
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
|
||||
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<STIME>1309275252</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
|
||||
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
|
||||
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
|
||||
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
|
||||
<TEMPLATE>
|
||||
<CPU><![CDATA[1]]></CPU>
|
||||
<MEMORY><![CDATA[1024]]></MEMORY>
|
||||
<NAME><![CDATA[PEPEPE]]></NAME>
|
||||
<VCPU><![CDATA[1]]></VCPU>
|
||||
<VMID><![CDATA[4]]></VMID>
|
||||
</TEMPLATE>
|
||||
<% if history = vm[:history] %>
|
||||
<HISTORY_RECORDS>
|
||||
<% history.each do |h| %>
|
||||
<HISTORY>
|
||||
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
|
||||
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
|
||||
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
|
||||
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
|
||||
<STIME>1309275256</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<VMMMAD>vmm_dummy</VMMMAD>
|
||||
<TMMAD>tm_dummy</TMMAD>
|
||||
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
|
||||
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
|
||||
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
|
||||
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
|
||||
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
|
||||
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
|
||||
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
|
||||
</HISTORY>
|
||||
<% end %>
|
||||
</HISTORY_RECORDS>
|
||||
<% end %>
|
||||
</VM>
|
@ -1,49 +0,0 @@
|
||||
<VM_POOL>
|
||||
<% vms.each do |id,vm| %>
|
||||
<VM>
|
||||
<ID><%= id %></ID>
|
||||
<UID><%= vm[:uid] ? vm[:uid] : 0 %></UID>
|
||||
<GID><%= vm[:gid] ? vm[:gid] : 0 %></GID>
|
||||
<NAME><%= vm[:name] ? vm[:uid] : 'pepe' %></NAME>
|
||||
<LAST_POLL><%= vm[:last_poll] ? vm[:last_poll] : '1309275256' %></LAST_POLL>
|
||||
<STATE><%= vm[:state] ? vm[:state] : 3 %></STATE>
|
||||
<LCM_STATE>3</LCM_STATE>
|
||||
<STIME>1309275252</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<DEPLOY_ID>dummy</DEPLOY_ID>
|
||||
<MEMORY><%= vm[:memory] ? vm[:memory] : 128 %></MEMORY>
|
||||
<CPU><%= vm[:cpu] ? vm[:cpu] : 1 %></CPU>
|
||||
<NET_TX><%= vm[:net_tx] ? vm[:net_tx] : 0 %></NET_TX>
|
||||
<NET_RX><%= vm[:net_rx] ? vm[:net_rx] : 0 %></NET_RX>
|
||||
<TEMPLATE>
|
||||
<CPU><![CDATA[<%= vm[:cpu] ? vm[:cpu] : 1 %>]]></CPU>
|
||||
<MEMORY><![CDATA[<%= vm[:memory] ? vm[:memory] : 128 %>]]></MEMORY>
|
||||
<NAME><![CDATA[PEPEPE]]></NAME>
|
||||
<VCPU><![CDATA[1]]></VCPU>
|
||||
<VMID><![CDATA[4]]></VMID>
|
||||
</TEMPLATE>
|
||||
<% if history = vm[:history] %>
|
||||
<HISTORY_RECORDS>
|
||||
<% h = history.last %>
|
||||
<HISTORY>
|
||||
<SEQ><%= h[:seq] ? h[:seq] : 0 %></SEQ>
|
||||
<HOSTNAME><%= h[:hostname] ? h[:hostname] : "kvxen" %></HOSTNAME>
|
||||
<VM_DIR>/Users/dmolina/trabajo/acctmoni/install/var/</VM_DIR>
|
||||
<HID><%= h[:hid] ? h[:hid] : 0 %></HID>
|
||||
<STIME>1309275256</STIME>
|
||||
<ETIME>0</ETIME>
|
||||
<VMMMAD>vmm_dummy</VMMMAD>
|
||||
<TMMAD>tm_dummy</TMMAD>
|
||||
<PSTIME><%= h[:pstime] ? h[:pstime] : 0 %></PSTIME>
|
||||
<PETIME><%= h[:petime] ? h[:petime] : 0 %></PETIME>
|
||||
<RSTIME><%= h[:rstime] ? h[:rstime] : 0 %></RSTIME>
|
||||
<RETIME><%= h[:retime] ? h[:retime] : 0 %></RETIME>
|
||||
<ESTIME><%= h[:estime] ? h[:estime] : 0 %></ESTIME>
|
||||
<EETIME><%= h[:eetime] ? h[:eetime] : 0 %></EETIME>
|
||||
<REASON><%= h[:reason] ? h[:reason] : 0 %></REASON>
|
||||
</HISTORY>
|
||||
</HISTORY_RECORDS>
|
||||
<% end %>
|
||||
</VM>
|
||||
<% end %>
|
||||
</VM_POOL>
|
@ -1,53 +0,0 @@
|
||||
require 'erb'
|
||||
|
||||
FPATH = "./fixtures/"
|
||||
|
||||
class MockClient
|
||||
def initialize
|
||||
@vms = Hash.new
|
||||
@done_vms = Hash.new
|
||||
|
||||
@images = Hash.new
|
||||
end
|
||||
|
||||
|
||||
def call(action, *args)
|
||||
xmlrpc_action = "one."+action
|
||||
|
||||
case xmlrpc_action
|
||||
when "one.vm.info"
|
||||
id = args[0]
|
||||
vm = @vms[id]
|
||||
return ERB.new(File.read(FPATH+'vm.xml')).result(binding)
|
||||
when "one.vmpool.info"
|
||||
case args[3]
|
||||
when -1
|
||||
vms = @vms
|
||||
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
|
||||
when 6 then
|
||||
vms = @done_vms
|
||||
return ERB.new(File.read(FPATH+'vmpool.xml')).result(binding)
|
||||
end
|
||||
when "one.imagepool.info"
|
||||
images = @images
|
||||
return ERB.new(File.read(FPATH+'imagepool.xml')).result(binding)
|
||||
end
|
||||
end
|
||||
|
||||
def add_vm(id, values)
|
||||
if values[:state] == 6
|
||||
@done_vms[id] = values.clone
|
||||
else
|
||||
@vms[id] = values.clone
|
||||
end
|
||||
end
|
||||
|
||||
def delete_vm(id)
|
||||
@vms.delete(id)
|
||||
@vms_done.delete(id)
|
||||
end
|
||||
|
||||
def add_image(id, values)
|
||||
@images[id] = values
|
||||
end
|
||||
end
|
@ -1,31 +0,0 @@
|
||||
|
||||
ONE_LOCATION = ENV['ONE_LOCATION']
|
||||
if !ONE_LOCATION
|
||||
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
|
||||
else
|
||||
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
|
||||
end
|
||||
|
||||
$: << RUBY_LIB_LOCATION
|
||||
|
||||
$: << './helper'
|
||||
$: << '.'
|
||||
$: << '..'
|
||||
|
||||
require 'mock_client'
|
||||
require 'OpenNebula'
|
||||
require 'quota'
|
||||
|
||||
class Quota
|
||||
def set_client(client)
|
||||
@client = client
|
||||
end
|
||||
|
||||
def rm_and_set_testdb
|
||||
`rm -f /tmp/onequota_test.db`
|
||||
@db=Sequel.connect("sqlite:///tmp/onequota_test.db")
|
||||
|
||||
create_table(QUOTA_TABLE)
|
||||
create_table(USAGE_TABLE)
|
||||
end
|
||||
end
|
@ -1,343 +0,0 @@
|
||||
$: << '.'
|
||||
|
||||
require 'helper/test_helper'
|
||||
|
||||
describe "Quota testing" do
|
||||
before(:all) do
|
||||
@mock_client = MockClient.new
|
||||
|
||||
@quota = Quota.new
|
||||
@quota.set_client(@mock_client)
|
||||
@quota.rm_and_set_testdb
|
||||
|
||||
@uid1 = 0
|
||||
@quota1 = {
|
||||
:CPU => 2.4,
|
||||
:MEMORY => 1024,
|
||||
:NUM_VMS => 4,
|
||||
:STORAGE => 10000
|
||||
}
|
||||
|
||||
@uid2 = 1
|
||||
@quota2 = {
|
||||
:CPU => 1.2,
|
||||
:MEMORY => 512,
|
||||
:NUM_VMS => 2,
|
||||
:STORAGE => 5000
|
||||
}
|
||||
|
||||
# Generate VM ACL request
|
||||
vm_template = <<-EOT
|
||||
<TEMPLATE>
|
||||
<CPU>2</CPU>
|
||||
<MEMORY>128</MEMORY>
|
||||
</TEMPLATE>
|
||||
EOT
|
||||
|
||||
vm_base64 = Base64::encode64(vm_template)
|
||||
@acl_vm_create = "VM:#{vm_base64}:CREATE:0:1:1"
|
||||
|
||||
# Generate IMAGE ACL request
|
||||
image_template = <<-EOT
|
||||
<TEMPLATE>
|
||||
<PATH>/etc/hosts</PATH>
|
||||
</TEMPLATE>
|
||||
EOT
|
||||
|
||||
image_base64 = Base64::encode64(image_template)
|
||||
@acl_image_create = "IMAGE:#{image_base64}:CREATE:0:1:1"
|
||||
|
||||
# Generate TEMPLATE ACL request
|
||||
temp_template = <<-EOT
|
||||
<TEMPLATE>
|
||||
<CPU>2</CPU>
|
||||
<MEMORY>128</MEMORY>
|
||||
</TEMPLATE>
|
||||
EOT
|
||||
|
||||
temp_base64 = Base64::encode64(temp_template)
|
||||
@acl_template_instantiate = "TEMPLATE:#{temp_base64}:INSTANTIATE:0:1:1"
|
||||
end
|
||||
|
||||
it "should check default quotas" do
|
||||
quota1 = @quota.get_quota(@uid1)
|
||||
quota1[:UID].should eql(0)
|
||||
quota1[:NUM_VMS].should eql(nil)
|
||||
quota1[:CPU].should eql(nil)
|
||||
quota1[:MEMORY].should eql(nil)
|
||||
quota1[:STORAGE].should eql(nil)
|
||||
end
|
||||
|
||||
it "should check default usage cache" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(nil)
|
||||
usage1cache[:CPU].should eql(nil)
|
||||
usage1cache[:MEMORY].should eql(nil)
|
||||
usage1cache[:STORAGE].should eql(nil)
|
||||
end
|
||||
|
||||
it "should check default cache (force)" do
|
||||
usage1force = @quota.get_usage(@uid1, nil, true)
|
||||
usage1force[:UID].should eql(0)
|
||||
usage1force[:NUM_VMS].should eql(0)
|
||||
usage1force[:CPU].should eql(0)
|
||||
usage1force[:MEMORY].should eql(0)
|
||||
usage1force[:STORAGE].should eql(0)
|
||||
end
|
||||
|
||||
it "should authorize the user because there is no quota defined" do
|
||||
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_image_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
|
||||
end
|
||||
|
||||
it "should add a new VM" do
|
||||
values = {
|
||||
:CPU => 2,
|
||||
:MEMORY => 128,
|
||||
:UID => 2,
|
||||
:GID => 4,
|
||||
}
|
||||
|
||||
@mock_client.add_vm(0, values)
|
||||
end
|
||||
|
||||
it "should check the usage cache is not updated" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(0)
|
||||
usage1cache[:CPU].should eql(0.0)
|
||||
usage1cache[:MEMORY].should eql(0)
|
||||
usage1cache[:STORAGE].should eql(0)
|
||||
end
|
||||
|
||||
it "should check the cache (force)" do
|
||||
usage1force = @quota.get_usage(@uid1, nil, true)
|
||||
usage1force[:UID].should eql(0)
|
||||
usage1force[:NUM_VMS].should eql(1)
|
||||
usage1force[:CPU].should eql(2.0)
|
||||
usage1force[:MEMORY].should eql(128)
|
||||
usage1force[:STORAGE].should eql(0)
|
||||
end
|
||||
|
||||
it "should check the usage cache is updated and contains the last usage" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1)
|
||||
usage1cache[:CPU].should eql(2.0)
|
||||
usage1cache[:MEMORY].should eql(128)
|
||||
usage1cache[:STORAGE].should eql(0)
|
||||
end
|
||||
|
||||
it "should add a new Image" do
|
||||
values = {
|
||||
:UID => 2,
|
||||
:GID => 4,
|
||||
:SIZE => 1000
|
||||
}
|
||||
|
||||
@mock_client.add_image(0, values)
|
||||
end
|
||||
|
||||
it "should check the usage cache is not updated" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1)
|
||||
usage1cache[:CPU].should eql(2.0)
|
||||
usage1cache[:MEMORY].should eql(128)
|
||||
usage1cache[:STORAGE].should eql(0)
|
||||
end
|
||||
|
||||
it "should check the cache (force)" do
|
||||
usage1force = @quota.get_usage(@uid1, nil, true)
|
||||
usage1force[:UID].should eql(0)
|
||||
usage1force[:NUM_VMS].should eql(1)
|
||||
usage1force[:CPU].should eql(2.0)
|
||||
usage1force[:MEMORY].should eql(128)
|
||||
usage1force[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should check the usage cache is updated and contains the last usage" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1)
|
||||
usage1cache[:CPU].should eql(2.0)
|
||||
usage1cache[:MEMORY].should eql(128)
|
||||
usage1cache[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should add a second VM" do
|
||||
values = {
|
||||
:CPU => 2,
|
||||
:MEMORY => 128,
|
||||
:UID => 2,
|
||||
:GID => 4,
|
||||
}
|
||||
|
||||
@mock_client.add_vm(1, values)
|
||||
end
|
||||
|
||||
it "should check the usage cache is not updated" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1)
|
||||
usage1cache[:CPU].should eql(2.0)
|
||||
usage1cache[:MEMORY].should eql(128)
|
||||
usage1cache[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should check the cache (force)" do
|
||||
usage1force = @quota.get_usage(@uid1, nil, true)
|
||||
usage1force[:UID].should eql(0)
|
||||
usage1force[:NUM_VMS].should eql(1*2)
|
||||
usage1force[:CPU].should eql(2.0*2)
|
||||
usage1force[:MEMORY].should eql(128*2)
|
||||
usage1force[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should check the usage cache is updated and contains the last usage" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1*2)
|
||||
usage1cache[:CPU].should eql(2.0*2)
|
||||
usage1cache[:MEMORY].should eql(128*2)
|
||||
usage1cache[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should add a second Image" do
|
||||
values = {
|
||||
:UID => 2,
|
||||
:GID => 4,
|
||||
:SIZE => 1000
|
||||
}
|
||||
|
||||
@mock_client.add_image(1, values)
|
||||
end
|
||||
|
||||
it "should check the usage cache is not updated" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1*2)
|
||||
usage1cache[:CPU].should eql(2.0*2)
|
||||
usage1cache[:MEMORY].should eql(128*2)
|
||||
usage1cache[:STORAGE].should eql(1000)
|
||||
end
|
||||
|
||||
it "should check the cache (force)" do
|
||||
usage1force = @quota.get_usage(@uid1, nil, true)
|
||||
usage1force[:UID].should eql(0)
|
||||
usage1force[:NUM_VMS].should eql(1*2)
|
||||
usage1force[:CPU].should eql(2.0*2)
|
||||
usage1force[:MEMORY].should eql(128*2)
|
||||
usage1force[:STORAGE].should eql(1000*2)
|
||||
end
|
||||
|
||||
it "should check the usage cache is updated and contains the last usage" do
|
||||
usage1cache = @quota.get_usage(@uid1)
|
||||
usage1cache[:UID].should eql(0)
|
||||
usage1cache[:NUM_VMS].should eql(1*2)
|
||||
usage1cache[:CPU].should eql(2.0*2)
|
||||
usage1cache[:MEMORY].should eql(128*2)
|
||||
usage1cache[:STORAGE].should eql(1000*2)
|
||||
end
|
||||
|
||||
it "should add a new quota and check it" do
|
||||
@quota.set_quota(@uid1, @quota1)
|
||||
|
||||
quota = @quota.get_quota(@uid1)
|
||||
@quota1.each{ |key,value|
|
||||
quota[key].should eql(value)
|
||||
}
|
||||
end
|
||||
|
||||
it "should not authorize the user because the vm quota is spent" do
|
||||
err_msg = "CPU quota exceeded (Quota: 2.4, Used: 4.0, Requested: 2.0)"
|
||||
@quota.authorize(@uid1, @acl_vm_create).should eql(err_msg)
|
||||
@quota.authorize(@uid1, @acl_template_instantiate).should eql(err_msg)
|
||||
|
||||
@quota.authorize(@uid1, @acl_image_create).should eql(false)
|
||||
end
|
||||
|
||||
it "should add a new quota for another user and check it" do
|
||||
@quota.set_quota(@uid2, @quota2)
|
||||
|
||||
quota = @quota.get_quota(@uid2)
|
||||
@quota2.each{ |key,value|
|
||||
quota[key].should eql(value)
|
||||
}
|
||||
end
|
||||
|
||||
it "should list all the defined quotas" do
|
||||
quotas = @quota.get_quota
|
||||
quotas.each { |quota|
|
||||
if quota[:UID] == @uid1
|
||||
@quota1.each{ |key,value|
|
||||
quota[key].should eql(value)
|
||||
}
|
||||
elsif quota[:UID] == @uid2
|
||||
@quota2.each{ |key,value|
|
||||
quota[key].should eql(value)
|
||||
}
|
||||
end
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
it "should update the first user quota and check it" do
|
||||
new_quota = Hash.new
|
||||
@quota1.each { |key,value|
|
||||
new_quota[key] = value*3
|
||||
}
|
||||
|
||||
@quota.set_quota(@uid1, new_quota)
|
||||
|
||||
quota = @quota.get_quota(@uid1)
|
||||
new_quota.each{ |key,value|
|
||||
quota[key] == value
|
||||
}
|
||||
end
|
||||
|
||||
it "should authorize the user because the quota is not spent" do
|
||||
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_image_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
|
||||
end
|
||||
|
||||
it "should update the first user quota and check it" do
|
||||
new_quota = {
|
||||
:STORAGE => 0
|
||||
}
|
||||
|
||||
@quota.set_quota(@uid1, new_quota)
|
||||
|
||||
quota = @quota.get_quota(@uid1)
|
||||
|
||||
quota[:STORAGE].should eql(new_quota[:STORAGE])
|
||||
end
|
||||
|
||||
it "should not authorize the user because the image quota is spent" do
|
||||
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
|
||||
|
||||
err_msg = "STORAGE quota exceeded (Quota: 0, Used: 2000, Requested: 271)"
|
||||
@quota.authorize(@uid1, @acl_image_create).should eql(err_msg)
|
||||
end
|
||||
|
||||
it "should delete the quota and check it" do
|
||||
@quota.delete_quota(@uid1)
|
||||
|
||||
quota1 = @quota.get_quota(@uid1)
|
||||
quota1[:UID].should eql(0)
|
||||
quota1[:NUM_VMS].should eql(nil)
|
||||
quota1[:CPU].should eql(nil)
|
||||
quota1[:MEMORY].should eql(nil)
|
||||
quota1[:STORAGE].should eql(nil)
|
||||
end
|
||||
|
||||
it "should authorize the user because the quota was deleted" do
|
||||
@quota.authorize(@uid1, @acl_vm_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_image_create).should eql(false)
|
||||
@quota.authorize(@uid1, @acl_template_instantiate).should eql(false)
|
||||
end
|
||||
end
|
@ -1,209 +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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
require 'cli_helper'
|
||||
|
||||
class OneQuotaHelper
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Tables to format user quotas
|
||||
#---------------------------------------------------------------------------
|
||||
TABLE_DS = CLIHelper::ShowTable.new(nil, self) do
|
||||
column :"DATASTORE ID", "", :left, :size=>12 do |d|
|
||||
d["ID"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"IMAGES (used)", "", :right, :size=>14 do |d|
|
||||
d["IMAGES_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"IMAGES (limit)", "", :right, :size=>14 do |d|
|
||||
d["IMAGES"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"SIZE (used)", "", :right, :size=>14 do |d|
|
||||
d["SIZE_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"SIZE (limit)", "", :right, :size=>14 do |d|
|
||||
d["SIZE"] if !d.nil?
|
||||
end
|
||||
end
|
||||
|
||||
TABLE_NET = CLIHelper::ShowTable.new(nil, self) do
|
||||
column :"NETWORK ID", "", :left, :size=>12 do |d|
|
||||
d["ID"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"LEASES (used)", "", :right, :size=>14 do |d|
|
||||
d["LEASES_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"LEASES (limit)", "", :right, :size=>14 do |d|
|
||||
d["LEASES"] if !d.nil?
|
||||
end
|
||||
end
|
||||
|
||||
TABLE_VM = CLIHelper::ShowTable.new(nil, self) do
|
||||
column :"VMS", "", :left, :size=>12 do |d|
|
||||
d["VMS"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"MEMORY (used)", "", :right, :size=>14 do |d|
|
||||
d["MEMORY_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"MEMORY (limit)", "", :right, :size=>14 do |d|
|
||||
d["MEMORY"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"CPU (used)", "", :right, :size=>14 do |d|
|
||||
d["CPU_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"CPU (limit)", "", :right, :size=>14 do |d|
|
||||
d["CPU"] if !d.nil?
|
||||
end
|
||||
end
|
||||
|
||||
TABLE_IMG = CLIHelper::ShowTable.new(nil, self) do
|
||||
column :"IMAGE ID", "", :left, :size=>12 do |d|
|
||||
d["ID"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"RVMS (used)", "", :right, :size=>14 do |d|
|
||||
d["RVMS_USED"] if !d.nil?
|
||||
end
|
||||
|
||||
column :"RVMS (limit)", "", :right, :size=>14 do |d|
|
||||
d["RVMS"] if !d.nil?
|
||||
end
|
||||
end
|
||||
|
||||
HELP_QUOTA = <<-EOT.unindent
|
||||
#-----------------------------------------------------------------------
|
||||
# Supported quota limits:
|
||||
#
|
||||
# DATASTORE = [
|
||||
# ID = <ID of the datastore>
|
||||
# IMAGES = <Max. number of images in the datastore>
|
||||
# SIZE = <Max. storage capacity (Mb) used in the datastore>
|
||||
# ]
|
||||
#
|
||||
# VM = [
|
||||
# VMS = <Max. number of VMs>
|
||||
# MEMORY = <Max. allocated memory (Mb)>
|
||||
# CPU = <Max. allocated CPU>
|
||||
# ]
|
||||
#
|
||||
# NETWORK = [
|
||||
# ID = <ID of the network>
|
||||
# LEASES = <Max. number of IP leases from the network>
|
||||
# ]
|
||||
#
|
||||
# IMAGE = [
|
||||
# ID = <ID of the image>
|
||||
# RVMS = <Max. number of VMs using the image>
|
||||
# ]
|
||||
#
|
||||
# In any quota 0 means unlimited. The usage counters "*_USED" are
|
||||
# shown for information purposes and will NOT be modified.
|
||||
#-----------------------------------------------------------------------
|
||||
EOT
|
||||
|
||||
# Edits the quota template of a resource
|
||||
# @param resource [PoolElement] to get the current info from
|
||||
# @param path [String] path to the new contents. If nil a editor will be
|
||||
# used
|
||||
# @return [String] contents of the new quotas
|
||||
def self.set_quota(resource, path)
|
||||
str = ""
|
||||
|
||||
if path.nil?
|
||||
require 'tempfile'
|
||||
|
||||
tmp = Tempfile.new('one-cli')
|
||||
path = tmp.path
|
||||
|
||||
rc = resource.info
|
||||
|
||||
if OpenNebula.is_error?(rc)
|
||||
puts rc.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
tmp << HELP_QUOTA
|
||||
tmp << resource.template_like_str("DATASTORE_QUOTA") << "\n"
|
||||
tmp << resource.template_like_str("VM_QUOTA") << "\n"
|
||||
tmp << resource.template_like_str("NETWORK_QUOTA") << "\n"
|
||||
tmp << resource.template_like_str("IMAGE_QUOTA") << "\n"
|
||||
|
||||
tmp.close
|
||||
|
||||
editor_path = ENV["EDITOR"] ? ENV["EDITOR"] : EDITOR_PATH
|
||||
system("#{editor_path} #{path}")
|
||||
|
||||
unless $?.exitstatus == 0
|
||||
puts "Editor not defined"
|
||||
exit -1
|
||||
end
|
||||
|
||||
str = File.read(path)
|
||||
|
||||
File.unlink(path)
|
||||
else
|
||||
str = File.read(path)
|
||||
end
|
||||
|
||||
str
|
||||
end
|
||||
|
||||
# Outputs formated quota information to stdout
|
||||
# @param qh [Hash] with the quotas for a given resource
|
||||
#
|
||||
def self.format_quota(qh)
|
||||
str_h1="%-80s"
|
||||
|
||||
puts
|
||||
|
||||
CLIHelper.print_header(str_h1 % "RESOURCE USAGE & QUOTAS",false)
|
||||
|
||||
puts
|
||||
|
||||
ds_quotas = [qh['DATASTORE_QUOTA']['DATASTORE']].flatten
|
||||
if !ds_quotas[0].nil?
|
||||
TABLE_DS.show(ds_quotas, {})
|
||||
puts
|
||||
end
|
||||
|
||||
vm_quotas = [qh['VM_QUOTA']['VM']].flatten
|
||||
if !vm_quotas[0].nil?
|
||||
TABLE_VM.show(vm_quotas, {})
|
||||
puts
|
||||
end
|
||||
|
||||
net_quotas = [qh['NETWORK_QUOTA']['NETWORK']].flatten
|
||||
if !net_quotas[0].nil?
|
||||
TABLE_NET.show(net_quotas, {})
|
||||
puts
|
||||
end
|
||||
|
||||
image_quotas = [qh['IMAGE_QUOTA']['IMAGE']].flatten
|
||||
if !image_quotas[0].nil?
|
||||
TABLE_IMG.show(image_quotas, {})
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user