diff --git a/src/oca/ruby/opennebula/oneflow_client.rb b/src/oca/ruby/opennebula/oneflow_client.rb index 128115f316..fdd5af47f2 100644 --- a/src/oca/ruby/opennebula/oneflow_client.rb +++ b/src/oca/ruby/opennebula/oneflow_client.rb @@ -21,6 +21,7 @@ require 'cloud/CloudClient' include CloudCLI module Role + # Actions that can be performed on the VMs of a given Role SCHEDULE_ACTIONS = [ 'terminate', @@ -78,8 +79,9 @@ module Role # @param [String] state String number representing the state # @return the state string def self.state_str(state_number) - return STATE_STR[state_number.to_i] + STATE_STR[state_number.to_i] end + end module Service @@ -126,19 +128,19 @@ module Service # @param [String] state String number representing the state # @return the state string def self.state_str(state_number) - return STATE_STR[state_number.to_i] + STATE_STR[state_number.to_i] end # Build a json specifying an action # @param [String] perform action to be performed (e.g.: shutdown) # @param [Hash, nil] params contains the params for the action # @return [String] json representing the action - def self.build_json_action(perform, params=nil) - body = Hash.new + def self.build_json_action(perform, params = nil) + body = {} body['perform'] = perform body['params'] = params if params - action = Hash.new + action = {} action['action'] = body JSON.pretty_generate action @@ -148,83 +150,83 @@ module Service DEFAULT_OPTIONS = [ ENDPOINT = { - :name => "server", - :short => "-s url", - :large => "--server url", + :name => 'server', + :short => '-s url', + :large => '--server url', :format => String, - :description => "Service endpoint" + :description => 'Service endpoint' }, USERNAME={ - :name => "username", - :short => "-u name", - :large => "--username name", + :name => 'username', + :short => '-u name', + :large => '--username name', :format => String, - :description => "User name" + :description => 'User name' }, PASSWORD={ - :name => "password", - :short => "-p pass", - :large => "--password pass", + :name => 'password', + :short => '-p pass', + :large => '--password pass', :format => String, - :description => "User password" + :description => 'User password' } ] JSON_FORMAT = { - :name => "json", - :short => "-j", - :large => "--json", - :description => "Print the resource in JSON" + :name => 'json', + :short => '-j', + :large => '--json', + :description => 'Print the resource in JSON' } TOP = { - :name => "top", - :short => "-t", - :large => "--top", - :description => "Top for the command" + :name => 'top', + :short => '-t', + :large => '--top', + :description => 'Top for the command' } PERIOD = { - :name => "period", - :short => "-p x", - :large => "--period x", + :name => 'period', + :short => '-p x', + :large => '--period x', :format => Integer, - :description => "Seconds between each group of actions" + :description => 'Seconds between each group of actions' } NUMBER = { - :name => "number", - :short => "-n x", - :large => "--number x", + :name => 'number', + :short => '-n x', + :large => '--number x', :format => Integer, - :description => "Number of VMs to apply the action to each period" + :description => 'Number of VMs to apply the action to each period' } FORCE = { - :name => "force", - :short => "-f", - :large => "--force", - :description => "Force the new cardinality even if it is outside the limits" + :name => 'force', + :short => '-f', + :large => '--force', + :description => 'Force the new cardinality even if it is outside the limits' } # Format helpers -# def self.rname_to_id(name, poolname, options) + # def self.rname_to_id(name, poolname, options) def self.rname_to_id(name, poolname) return 0, name.to_i if name.match(/^[0123456789]+$/) - client = Service::Client.new() + client = Service::Client.new resource_path = case poolname - when "SERVICE" then "/service" - when "SERVICE TEMPLATE" then "/service_template" - end + when 'SERVICE' then '/service' + when 'SERVICE TEMPLATE' then '/service_template' + end response = client.get(resource_path) - if CloudClient::is_error?(response) + if CloudClient.is_error?(response) return -1, "OpenNebula #{poolname} name not found," << - " use the ID instead" + ' use the ID instead' end pool = JSON.parse(response.body) @@ -242,38 +244,32 @@ module Service objects = pool['DOCUMENT_POOL']['DOCUMENT'].select {|object| object['NAME'] == name } - if objects.length>0 - if objects.length>1 - return -1, "There are multiple #{ename}s with name #{name}." - else - result = objects.first['ID'] - end - else - return -1, "#{ename} named #{name} not found." - end + return -1, "#{ename} named #{name} not found." unless objects.length>0 + return -1, "There are multiple #{ename}s with name #{name}." if objects.length>1 - return 0, result + result = objects.first['ID'] + + [0, result] end def self.list_to_id(names, poolname) - - client = Service::Client.new() + client = Service::Client.new resource_path = case poolname - when "SERVICE" then "/service" - when "SERVICE TEMPLATE" then "/service_template" - end + when 'SERVICE' then '/service' + when 'SERVICE TEMPLATE' then '/service_template' + end response = client.get(resource_path) - if CloudClient::is_error?(response) + if CloudClient.is_error?(response) return -1, "OpenNebula #{poolname} name not found," << - " use the ID instead" + ' use the ID instead' end pool = JSON.parse(response.body) - result = names.split(',').collect { |name| + result = names.split(',').collect do |name| if name.match(/^[0123456789]+$/) name.to_i else @@ -285,9 +281,9 @@ module Service rc[1] end - } + end - return 0, result + [0, result] end def self.list_to_id_desc(poolname) @@ -304,8 +300,8 @@ module Service ids.each do |id| response = block.call(id) if block_given? - if CloudClient::is_error?(response) - puts response.to_s + if CloudClient.is_error?(response) + puts response exit_code = response.code.to_i end end @@ -321,16 +317,29 @@ module Service exit_code = 0 response = block.call(id) if block_given? - if CloudClient::is_error?(response) - puts response.to_s + if CloudClient.is_error?(response) + puts response exit_code = response.code.to_i end exit_code end + # + # Interface to OneFlow REST API through a Ruby client + # class Client - def initialize(opts={}) + + # + # The options are read from ENV and FS if not passed + # + # @param [Hash] opts Required configuration to interact with OneFlow + # @option opts [String] :url Endpoint where OneFlow is running. Defaults to 'http://localhost:2474' + # @option opts [String] :username OpenNebula user + # @option opts [String] :password OpenNebula user password + # @option opts [String] :user_agent Defaults to Ruby. Oneflow will behave accordingly. + # + def initialize(opts = {}) endpoint = '/.one/oneflow_endpoint' @username = opts[:username] || ENV['ONEFLOW_USER'] @password = opts[:password] || ENV['ONEFLOW_PASSWORD'] @@ -348,14 +357,14 @@ module Service end if @username.nil? && @password.nil? - if ENV["ONE_AUTH"] and !ENV["ONE_AUTH"].empty? and File.file?(ENV["ONE_AUTH"]) - one_auth = File.read(ENV["ONE_AUTH"]) - elsif ENV["HOME"] and File.file?(ENV["HOME"]+"/.one/one_auth") - one_auth = File.read(ENV["HOME"]+"/.one/one_auth") - elsif File.file?("/var/lib/one/.one/one_auth") - one_auth = File.read("/var/lib/one/.one/one_auth") + if ENV['ONE_AUTH'] and !ENV['ONE_AUTH'].empty? and File.file?(ENV['ONE_AUTH']) + one_auth = File.read(ENV['ONE_AUTH']) + elsif ENV['HOME'] and File.file?(ENV['HOME']+'/.one/one_auth') + one_auth = File.read(ENV['HOME']+'/.one/one_auth') + elsif File.file?('/var/lib/one/.one/one_auth') + one_auth = File.read('/var/lib/one/.one/one_auth') else - raise "ONE_AUTH file not present" + raise 'ONE_AUTH file not present' end one_auth = one_auth.rstrip @@ -366,37 +375,37 @@ module Service @uri = URI.parse(url) @user_agent = "OpenNebula #{CloudClient::VERSION} " << - "(#{opts[:user_agent]||"Ruby"})" + "(#{opts[:user_agent]||'Ruby'})" @host = nil @port = nil - if ENV['http_proxy'] - uri_proxy = URI.parse(ENV['http_proxy']) - flag = false + return unless ENV['http_proxy'] - # Check if we need to bypass the proxy - if ENV['no_proxy'] - ENV['no_proxy'].split(',').each do |item| - item = item.rstrip.lstrip + uri_proxy = URI.parse(ENV['http_proxy']) + flag = false - unless (IPAddress @uri.host rescue nil).nil? - unless (IPAddress item rescue nil).nil? - flag |= IPAddress(item).include? IPAddress(@uri.host) - end - else - if (IPAddress(item) rescue nil).nil? - flag |= (item == @uri.host) - end + #  Check if we need to bypass the proxy + if ENV['no_proxy'] + ENV['no_proxy'].split(',').each do |item| + item = item.strip + + if (IPAddress @uri.host rescue nil).nil? + if (IPAddress(item) rescue nil).nil? + flag |= (item == @uri.host) + end + else + unless (IPAddress item rescue nil).nil? + flag |= IPAddress(item).include? IPAddress(@uri.host) end end end - - unless flag - @host = uri_proxy.host - @port = uri_proxy.port - end end + + return if flag + + @host = uri_proxy.host + @port = uri_proxy.port end def set_content_type(content_type) @@ -420,10 +429,8 @@ module Service req = Net::HTTP::Proxy(@host, @port)::Post.new(path) req.body = body - if path.start_with?('/service_template') - unless @content_type.nil? - req.content_type = @content_type - end + if path.start_with?('/service_template') && !@content_type.nil? + req.content_type = @content_type end do_request(req) end @@ -454,11 +461,11 @@ module Service req['User-Agent'] = @user_agent - res = CloudClient::http_start(@uri, @timeout) do |http| + CloudClient.http_start(@uri, @timeout) do |http| http.request(req) end - - res end + end + end