mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-02 10:50:07 +03:00
feature #1427: Refactor oneacct
This commit is contained in:
parent
435c5ea1b2
commit
521e6ff7c4
@ -1194,7 +1194,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \
|
||||
src/cli/one_helper/onevnet_helper.rb \
|
||||
src/cli/one_helper/oneacl_helper.rb \
|
||||
src/cli/one_helper/onedatastore_helper.rb \
|
||||
src/cli/one_helper/onecluster_helper.rb"
|
||||
src/cli/one_helper/onecluster_helper.rb \
|
||||
src/cli/one_helper/oneacct_helper.rb"
|
||||
|
||||
CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onehost \
|
||||
@ -1205,7 +1206,8 @@ CLI_BIN_FILES="src/cli/onevm \
|
||||
src/cli/onegroup \
|
||||
src/cli/oneacl \
|
||||
src/cli/onedatastore \
|
||||
src/cli/onecluster"
|
||||
src/cli/onecluster \
|
||||
src/cli/oneacct"
|
||||
|
||||
CLI_CONF_FILES="src/cli/etc/onegroup.yaml \
|
||||
src/cli/etc/onehost.yaml \
|
||||
|
179
src/cli/one_helper/oneacct_helper.rb
Normal file
179
src/cli/one_helper/oneacct_helper.rb
Normal file
@ -0,0 +1,179 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# 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 'one_helper'
|
||||
|
||||
class AcctHelper < OpenNebulaHelper::OneHelper
|
||||
START_TIME = {
|
||||
:name => "start_time",
|
||||
:short => "-s TIME",
|
||||
:large => "--start TIME" ,
|
||||
:description => "Start date and time to take into account",
|
||||
:format => String # TODO Time
|
||||
}
|
||||
|
||||
END_TIME = {
|
||||
:name => "end_time",
|
||||
:short => "-e TIME",
|
||||
:large => "--end TIME" ,
|
||||
:description => "End date and time",
|
||||
:format => String # TODO Time
|
||||
}
|
||||
|
||||
USER = {
|
||||
:name => "user",
|
||||
:short => "-u user",
|
||||
:large => "--user user" ,
|
||||
:description => "User name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
OpenNebulaHelper.rname_to_id(o, "USER")
|
||||
}
|
||||
}
|
||||
|
||||
GROUP = {
|
||||
:name => "group",
|
||||
:short => "-g group",
|
||||
:large => "--group group" ,
|
||||
:description => "Group name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
puts o
|
||||
OpenNebulaHelper.rname_to_id(o, "GROUP")
|
||||
}
|
||||
}
|
||||
|
||||
HOST = {
|
||||
:name => "host",
|
||||
:short => "-H HOST",
|
||||
:large => "--host HOST" ,
|
||||
:description => "Host name or id to filter the results",
|
||||
:format => String,
|
||||
:proc => lambda { |o, options|
|
||||
OpenNebulaHelper.rname_to_id(o, "HOST")
|
||||
}
|
||||
}
|
||||
|
||||
XPATH = {
|
||||
:name => "xpath",
|
||||
:large => "--xpath XPATH_EXPRESSION" ,
|
||||
:description => "Xpath expression to filter the results. \
|
||||
For example: oneacct --xpath 'HISTORY[ETIME>0]'",
|
||||
:format => String
|
||||
}
|
||||
|
||||
XML = {
|
||||
:name => "xml",
|
||||
:short => "-x",
|
||||
:large => "--xml",
|
||||
:description => "Show the resource in xml format"
|
||||
}
|
||||
|
||||
JSON = {
|
||||
:name => "json",
|
||||
:short => "-j",
|
||||
:large => "--json",
|
||||
:description => "Show the resource in xml format"
|
||||
}
|
||||
|
||||
SPLIT={
|
||||
:name => "split",
|
||||
:large => "--split",
|
||||
:description => "Split the output in a table for each VM"
|
||||
}
|
||||
|
||||
ACCT_OPTIONS = [START_TIME, END_TIME, USER, GROUP, HOST, XPATH, XML, JSON, SPLIT]
|
||||
|
||||
|
||||
ACCT_TABLE = CLIHelper::ShowTable.new("oneacct.yaml", nil) do
|
||||
column :VID, "Virtual Machine ID", :size=>4 do |d|
|
||||
d["OID"]
|
||||
end
|
||||
|
||||
column :SEQ, "History record sequence number", :size=>3 do |d|
|
||||
d["SEQ"]
|
||||
end
|
||||
|
||||
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
|
||||
d["HOSTNAME"]
|
||||
end
|
||||
|
||||
column :REASON, "VM state change reason", :left, :size=>4 do |d|
|
||||
VirtualMachine.get_reason d["REASON"]
|
||||
end
|
||||
|
||||
column :START_TIME, "Start time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['STIME'])
|
||||
end
|
||||
|
||||
column :END_TIME, "End time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['ETIME'])
|
||||
end
|
||||
|
||||
column :MEMORY, "Assigned memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["TEMPLATE"]["MEMORY"].to_i, {}, 'M')
|
||||
end
|
||||
|
||||
column :CPU, "Number of CPUs", :size=>3 do |d|
|
||||
d["VM"]["TEMPLATE"]["CPU"]
|
||||
end
|
||||
|
||||
column :NET_RX, "Data received from the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["NET_RX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
column :NET_TX, "Data sent to the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM"]["NET_TX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
|
||||
end
|
||||
|
||||
def self.print_start_enc_time_header(start_time, end_time)
|
||||
print "Showing active history records from "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
if ( start_time != -1 )
|
||||
print Time.at(start_time).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
print " to "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
if ( end_time != -1 )
|
||||
print Time.at(end_time).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
puts
|
||||
end
|
||||
|
||||
def self.print_user_header(user_id)
|
||||
CLIHelper.scr_bold
|
||||
CLIHelper.scr_underline
|
||||
puts "# User #{user_id}".ljust(80)
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
end
|
||||
end
|
390
src/cli/oneacct
390
src/cli/oneacct
@ -16,7 +16,6 @@
|
||||
# limitations under the License. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
ONE_LOCATION=ENV["ONE_LOCATION"]
|
||||
|
||||
if !ONE_LOCATION
|
||||
@ -28,356 +27,87 @@ end
|
||||
$: << RUBY_LIB_LOCATION
|
||||
$: << RUBY_LIB_LOCATION+"/cli"
|
||||
|
||||
require 'rubygems'
|
||||
require 'command_parser'
|
||||
require 'one_helper/oneacct_helper'
|
||||
|
||||
require 'cli/one_helper'
|
||||
require 'cli/command_parser'
|
||||
require 'json'
|
||||
|
||||
require 'optparse'
|
||||
require 'optparse/time'
|
||||
cmd = CommandParser::CmdParser.new(ARGV) do
|
||||
usage "`oneacct` [<options>]"
|
||||
description ""
|
||||
version OpenNebulaHelper::ONE_VERSION
|
||||
|
||||
|
||||
################################################################################
|
||||
# CLI Helper
|
||||
################################################################################
|
||||
option [AcctHelper::ACCT_OPTIONS + CommandParser::OPTIONS]
|
||||
|
||||
class AcctHelper < OpenNebulaHelper::OneHelper
|
||||
main do
|
||||
filter_flag = (options[:user] || VirtualMachinePool::INFO_ALL)
|
||||
start_time = options[:start] ? options[:start].to_i : -1
|
||||
end_time = options[:end] ? options[:end].to_i : -1
|
||||
|
||||
def self.conf_file
|
||||
"oneacct.yaml"
|
||||
end
|
||||
common_opts = {
|
||||
:start_time => start_time,
|
||||
:end_time => end_time,
|
||||
:host => options[:host],
|
||||
:group => options[:group],
|
||||
:xpath => options[:xpath]
|
||||
}
|
||||
|
||||
=begin
|
||||
List of <HISTORY> child elements
|
||||
client = OpenNebula::Client.new
|
||||
pool = OpenNebula::VirtualMachinePool.new(client)
|
||||
|
||||
OID
|
||||
SEQ
|
||||
HOSTNAME
|
||||
HID
|
||||
STIME
|
||||
ETIME
|
||||
VMMMAD
|
||||
VNMMAD
|
||||
PSTIME
|
||||
PETIME
|
||||
RSTIME
|
||||
RETIME
|
||||
ESTIME
|
||||
EETIME
|
||||
REASON
|
||||
=end
|
||||
|
||||
def list_history(data)
|
||||
table = CLIHelper::ShowTable.new(self.class.table_conf, self) do
|
||||
column :VID, "Virtual Machine ID", :size=>4 do |d|
|
||||
d["OID"]
|
||||
if options[:json] || options[:xml]
|
||||
xml_str = pool.accounting_xml(filter_flag, common_opts)
|
||||
if OpenNebula.is_error?(xml_str)
|
||||
puts acct_hash.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
column :SEQ, "History record sequence number", :size=>3 do |d|
|
||||
d["SEQ"]
|
||||
if options[:json]
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
puts xmldoc.to_hash.to_json
|
||||
elsif options[:xml]
|
||||
puts xml_str
|
||||
end
|
||||
|
||||
column :HOSTNAME, "Host name", :left, :size=>15 do |d|
|
||||
d["HOSTNAME"]
|
||||
exit_code 0
|
||||
else
|
||||
order_by = Hash.new
|
||||
order_by[:order_by_1] = 'VM/UID'
|
||||
order_by[:order_by_2] = 'VM/ID' if options[:split]
|
||||
|
||||
acct_hash = pool.accounting(filter_flag, common_opts.merge(order_by))
|
||||
if OpenNebula.is_error?(acct_hash)
|
||||
puts acct_hash.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
column :REASON, "VM state change reason", :left, :size=>4 do |d|
|
||||
VirtualMachine.get_reason d["REASON"]
|
||||
if ( start_time != -1 or end_time != -1 )
|
||||
AcctHelper.print_start_end_time_header(start_time, end_time)
|
||||
end
|
||||
|
||||
column :START_TIME, "Start time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['STIME'])
|
||||
end
|
||||
acct_hash.each { |user_id, value|
|
||||
AcctHelper.print_user_header(user_id)
|
||||
|
||||
column :END_TIME, "End time", :size=>14 do |d|
|
||||
OpenNebulaHelper.time_to_str(d['ETIME'])
|
||||
end
|
||||
|
||||
column :MEMORY, "Assigned memory", :size=>6 do |d|
|
||||
OpenNebulaHelper.unit_to_str(d["VM/TEMPLATE/MEMORY"].to_i, {}, 'M')
|
||||
end
|
||||
|
||||
column :CPU, "Number of CPUs", :size=>3 do |d|
|
||||
d["VM/TEMPLATE/CPU"]
|
||||
end
|
||||
|
||||
column :NET_RX, "Data received from the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM/NET_RX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
column :NET_TX, "Data sent to the network", :size=>6 do |d|
|
||||
# NET is measured in bytes, unit_to_str expects KBytes
|
||||
OpenNebulaHelper.unit_to_str(d["VM/NET_TX"].to_i / 1024.0, {})
|
||||
end
|
||||
|
||||
default :VID, :HOSTNAME, :REASON, :START_TIME, :END_TIME, :MEMORY, :CPU, :NET_RX, :NET_TX
|
||||
end
|
||||
|
||||
table.show(data)
|
||||
end
|
||||
|
||||
public
|
||||
def list_users(xmldoc, options=nil)
|
||||
|
||||
uids = xmldoc.retrieve_elements('HISTORY/VM/UID')
|
||||
|
||||
if uids.nil?
|
||||
puts "No records found."
|
||||
exit 0
|
||||
end
|
||||
|
||||
uids.uniq!
|
||||
|
||||
history_elems = []
|
||||
|
||||
uids.each do |uid|
|
||||
CLIHelper.scr_bold
|
||||
CLIHelper.scr_underline
|
||||
|
||||
username_elems =
|
||||
xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/UNAME")
|
||||
|
||||
username = username_elems.nil? ? "" : username_elems.uniq
|
||||
|
||||
puts "# User #{uid} #{username}".ljust(80)
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
|
||||
history_elems.clear
|
||||
|
||||
vm_ids = xmldoc.retrieve_elements("HISTORY/VM[UID=#{uid}]/ID")
|
||||
vm_ids = [] if vm_ids.nil?
|
||||
vm_ids.uniq!
|
||||
|
||||
vm_ids.each do |vid|
|
||||
|
||||
if ( options[:split] )
|
||||
history_elems.clear
|
||||
end
|
||||
|
||||
xmldoc.each("HISTORY[OID=#{vid}]") do |history|
|
||||
history_elems << history
|
||||
end
|
||||
|
||||
if ( options[:split] )
|
||||
list_history(history_elems)
|
||||
if options[:split]
|
||||
# Use one table for each VM
|
||||
value.each { |vm_id, history_array|
|
||||
array = history_array['HISTORY_RECORDS']['HISTORY']
|
||||
AcctHelper::ACCT_TABLE.show(array)
|
||||
puts
|
||||
}
|
||||
else
|
||||
# Use the same table for all the VMs
|
||||
array = value['HISTORY_RECORDS']['HISTORY']
|
||||
AcctHelper::ACCT_TABLE.show(array)
|
||||
puts
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
if ( !options[:split] )
|
||||
list_history(history_elems)
|
||||
puts
|
||||
end
|
||||
exit_code 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Helper methods
|
||||
################################################################################
|
||||
|
||||
def redo_xmldoc(xmldoc, xpath_str)
|
||||
xml_str = "<HISTORY_RECORDS>"
|
||||
|
||||
xmldoc.each(xpath_str) do |history|
|
||||
xml_str << history.to_xml
|
||||
end
|
||||
|
||||
xml_str << "</HISTORY_RECORDS>"
|
||||
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
return xmldoc
|
||||
end
|
||||
|
||||
################################################################################
|
||||
# Main command
|
||||
################################################################################
|
||||
|
||||
options = Hash.new
|
||||
|
||||
options[:format] = :table
|
||||
|
||||
opts = OptionParser.new do |opts|
|
||||
opts.on('-s', '--start TIME', Time,
|
||||
'Start date and time to take into account') do |ext|
|
||||
options[:start]=ext
|
||||
end
|
||||
|
||||
opts.on("-e", "--end TIME", Time,
|
||||
"End date and time" ) do |ext|
|
||||
options[:end]=ext
|
||||
end
|
||||
|
||||
opts.on("-u", "--user user", String,
|
||||
"User id to filter the results" ) do |ext|
|
||||
options[:user]=ext
|
||||
end
|
||||
|
||||
opts.on("-g", "--group group", String,
|
||||
"Group id to filter the results" ) do |ext|
|
||||
options[:group]=ext
|
||||
end
|
||||
|
||||
opts.on("-H", "--host hostname", String,
|
||||
"Host id to filter the results" ) do |ext|
|
||||
options[:host]=ext
|
||||
end
|
||||
|
||||
opts.on("--xpath expression", String,
|
||||
"Xpath expression to filter the results. For example: oneacct --xpath 'HISTORY[ETIME>0]'" ) do |ext|
|
||||
options[:xpath]=ext
|
||||
end
|
||||
|
||||
opts.on("-j", "--json",
|
||||
"Output in json format" ) do |ext|
|
||||
options[:format]=:json
|
||||
end
|
||||
|
||||
opts.on("-x", "--xml",
|
||||
"Output in xml format" ) do |ext|
|
||||
options[:format]=:xml
|
||||
end
|
||||
|
||||
opts.on("--split",
|
||||
"Split the output in a table for each VM" ) do |ext|
|
||||
options[:split]=ext
|
||||
end
|
||||
|
||||
opts.on("-h", "--help", "Show this message" ) do
|
||||
puts opts
|
||||
exit
|
||||
end
|
||||
|
||||
opts.on()
|
||||
end
|
||||
|
||||
|
||||
begin
|
||||
opts.parse!(ARGV)
|
||||
rescue OptionParser::ParseError => e
|
||||
STDERR.puts "Error: " << e.message
|
||||
exit(-1)
|
||||
end
|
||||
|
||||
|
||||
client = OpenNebula::Client.new
|
||||
|
||||
acct_helper = AcctHelper.new()
|
||||
|
||||
time_start = -1
|
||||
time_end = -1
|
||||
filter_flag = VirtualMachinePool::INFO_ALL
|
||||
|
||||
time_start = options[:start].to_i if options[:start]
|
||||
time_end = options[:end].to_i if options[:end]
|
||||
|
||||
if options[:user]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:user], "USER")
|
||||
|
||||
if rc[0] == 0
|
||||
filter_flag = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
xml_str = client.call("vmpool.accounting",
|
||||
filter_flag,
|
||||
time_start,
|
||||
time_end)
|
||||
|
||||
if OpenNebula.is_error?(xml_str)
|
||||
puts xml_str.message
|
||||
exit -1
|
||||
end
|
||||
|
||||
xmldoc = XMLElement.new
|
||||
xmldoc.initialize_xml(xml_str, 'HISTORY_RECORDS')
|
||||
|
||||
xpath = nil
|
||||
hid = nil
|
||||
gid = nil
|
||||
|
||||
if options[:host]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:host], "HOST")
|
||||
|
||||
if rc[0] == 0
|
||||
hid = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
if options[:group]
|
||||
rc = OpenNebulaHelper.rname_to_id(options[:group], "GROUP")
|
||||
|
||||
if rc[0] == 0
|
||||
gid = rc[1]
|
||||
else
|
||||
puts rc[1]
|
||||
exit -1
|
||||
end
|
||||
end
|
||||
|
||||
if options[:host] && options[:group]
|
||||
xpath = "HISTORY[VM/GID=#{gid} and HID=#{hid}]"
|
||||
elsif options[:host]
|
||||
xpath = "HISTORY[HID=#{hid}]"
|
||||
elsif options[:group]
|
||||
xpath = "HISTORY[VM/GID=#{gid}]"
|
||||
end
|
||||
|
||||
xmldoc = redo_xmldoc(xmldoc, xpath) if !xpath.nil?
|
||||
|
||||
|
||||
if options[:xpath]
|
||||
xmldoc = redo_xmldoc(xmldoc, options[:xpath])
|
||||
end
|
||||
|
||||
|
||||
case options[:format]
|
||||
when :table
|
||||
if ( time_start != -1 or time_end != -1 )
|
||||
print "Showing active history records from "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
|
||||
if ( time_start != -1 )
|
||||
print Time.at(time_start).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
|
||||
print " to "
|
||||
|
||||
CLIHelper.scr_bold
|
||||
|
||||
if ( time_end != -1 )
|
||||
print Time.at(time_end).to_s
|
||||
else
|
||||
print "-"
|
||||
end
|
||||
|
||||
CLIHelper.scr_restore
|
||||
puts
|
||||
puts
|
||||
end
|
||||
|
||||
acct_helper.list_users(xmldoc, options)
|
||||
|
||||
when :xml
|
||||
puts xmldoc.to_xml
|
||||
|
||||
when :json
|
||||
puts xmldoc.to_hash.to_json
|
||||
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user