From f000d0cf124d314fc5d3f24893140022ef097370 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Fri, 21 Dec 2012 17:26:24 +0400 Subject: [PATCH 01/32] Fix hostgroup for zabbix api 1.4 --- lib/rubix/connection.rb | 4 ++++ lib/rubix/models/host_group.rb | 7 ++++++- lib/rubix/models/model.rb | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/lib/rubix/connection.rb b/lib/rubix/connection.rb index 60c85eb..94c594d 100644 --- a/lib/rubix/connection.rb +++ b/lib/rubix/connection.rb @@ -134,6 +134,10 @@ def uri= uri_or_string return @server end + def api_version + @api_version ||= request('apiinfo.version', {}).parsed["result"] + end + protected # The parameters used for constructing an authorization request diff --git a/lib/rubix/models/host_group.rb b/lib/rubix/models/host_group.rb index f8779fc..cd990ae 100644 --- a/lib/rubix/models/host_group.rb +++ b/lib/rubix/models/host_group.rb @@ -37,7 +37,12 @@ def destroy_params end def self.get_params - super().merge(:select_hosts => :refer) + case api_version + when '1.4' + super().merge(:selectHosts => :refer) + else + super().merge(:select_hosts => :refer) + end end def self.find_params options={} diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index e1ce333..b0fa0f5 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -86,6 +86,18 @@ def request method, params self.class.request(method, params) end + # Return Zabbix API version + # @return [Rubix::Response] + def api_version + self.class.api_version + end + + # Return Zabbix API version + # @return [Rubix::Response] + def self.api_version + Rubix.connection && Rubix.connection.api_version + end + # Send a request to the Zabbix API. This is just a convenience # method for Rubix::Connection#request. # From a9bb20592f3a6ae497ae48001f28aca36fc8e7b3 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 24 Dec 2012 17:54:40 +0400 Subject: [PATCH 02/32] Support for API version 1.4 --- lib/rubix/connection.rb | 2 +- lib/rubix/models/host.rb | 7 ++++++- lib/rubix/models/model.rb | 4 ++-- lib/rubix/models/template.rb | 7 ++++++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/rubix/connection.rb b/lib/rubix/connection.rb index 94c594d..a1d6a11 100644 --- a/lib/rubix/connection.rb +++ b/lib/rubix/connection.rb @@ -135,7 +135,7 @@ def uri= uri_or_string end def api_version - @api_version ||= request('apiinfo.version', {}).parsed["result"] + @api_version ||= request('apiinfo.version', {}).result end protected diff --git a/lib/rubix/models/host.rb b/lib/rubix/models/host.rb index 3d33acc..2327c66 100644 --- a/lib/rubix/models/host.rb +++ b/lib/rubix/models/host.rb @@ -204,7 +204,12 @@ def self.build host end def self.get_params - super().merge({:select_groups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :select_macros => :extend}) + case api_version + when '1.4' + super().merge({:selectGroups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :selectMacros => :extend}) + else + super().merge({:select_groups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :select_macros => :extend}) + end end def self.find_params options={} diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index b0fa0f5..2496019 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -87,13 +87,13 @@ def request method, params end # Return Zabbix API version - # @return [Rubix::Response] + # @return [String] def api_version self.class.api_version end # Return Zabbix API version - # @return [Rubix::Response] + # @return [String] def self.api_version Rubix.connection && Rubix.connection.api_version end diff --git a/lib/rubix/models/template.rb b/lib/rubix/models/template.rb index 35c2929..81fa4c4 100644 --- a/lib/rubix/models/template.rb +++ b/lib/rubix/models/template.rb @@ -52,7 +52,12 @@ def destroy_params end def self.get_params - super().merge(:select_groups => :refer, :select_hosts => :refer) + case api_version + when '1.4' + super().merge(:selectGroups => :refer, :selectHosts => :refer) + else + super().merge(:select_groups => :refer, :select_hosts => :refer) + end end def self.find_params options={} From 3d751c09bde76424ec86ea9f17600507ee27931b Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 15 Jan 2013 19:20:36 +0400 Subject: [PATCH 03/32] VersionError added, this version works only with 2.0.4 --- lib/rubix.rb | 9 +++++++-- lib/rubix/connection.rb | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/rubix.rb b/lib/rubix.rb index 0afab8a..a6cb672 100644 --- a/lib/rubix.rb +++ b/lib/rubix.rb @@ -7,6 +7,8 @@ module Rubix + SERVER_VERSION = '2.0.4'.freeze + autoload :Connection, 'rubix/connection' autoload :Response, 'rubix/response' autoload :Sender, 'rubix/sender' @@ -77,7 +79,7 @@ def self.version File.read(File.expand_path('../../VERSION', __FILE__)).chomp rescue => e 'unknown' - end + end end # Base class for Rubix errors. @@ -99,5 +101,8 @@ def self.version # Given an incorrect argument. ArgumentError = Class.new(Error) - + + # Incorrect version of Zabbix server + VersionError = Class.new(Error) + end diff --git a/lib/rubix/connection.rb b/lib/rubix/connection.rb index a1d6a11..f3befe2 100644 --- a/lib/rubix/connection.rb +++ b/lib/rubix/connection.rb @@ -114,6 +114,9 @@ def authorize! raise AuthenticationError.new("Could not authenticate with Zabbix API at #{uri}: #{response.error_message}") if response.error? raise AuthenticationError.new("Malformed response from Zabbix API: #{response.body}") unless response.string? @auth = response.result + + raise VersionError.new("Incorrect Zabbix Server API version, should be #{SERVER_VERSION}") unless api_version == SERVER_VERSION + @auth end # Set the URI for this connection's Zabbix API server. From 019140ef01128b6da8cb87c986d0bb9912953e39 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 15 Jan 2013 21:11:00 +0400 Subject: [PATCH 04/32] Host creation spec passes on Zabbix 2.0.4 --- Gemfile | 1 + lib/rubix/models/host.rb | 80 ++++++++++++++++++------------ lib/rubix/models/host_group.rb | 7 +-- lib/rubix/models/template.rb | 7 +-- spec/requests/host_request_spec.rb | 17 ++++--- spec/support/integration_helper.rb | 43 ++++++++-------- 6 files changed, 81 insertions(+), 74 deletions(-) diff --git a/Gemfile b/Gemfile index 4753282..983f2f7 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,7 @@ end # Gems for testing and coverage group :test do gem 'simplecov', ">= 0.5", :platform => [:ruby_19], :require => false + gem 'pg' end # Gems you would use if hacking on this gem (rather than with it) diff --git a/lib/rubix/models/host.rb b/lib/rubix/models/host.rb index 2327c66..fe1848c 100644 --- a/lib/rubix/models/host.rb +++ b/lib/rubix/models/host.rb @@ -1,11 +1,24 @@ module Rubix class Host < Model + class Interface < Model + zabbix_attr :type, :default => 1 + zabbix_attr :main, :default => 1 + zabbix_attr :use_ip, :default => true + zabbix_attr :ip + zabbix_attr :dns, :default => '' + zabbix_attr :port + + def use_ip + return @use_ip if (!@use_ip.nil?) + @use_ip = true + end + end # # == Properties & Finding == # - + # The IP for a Host that not supposed to be polled by the Zabbix # server. BLANK_IP = '0.0.0.0' @@ -45,12 +58,9 @@ class Host < Model } zabbix_attr :name - zabbix_attr :ip - zabbix_attr :port + zabbix_attr :interfaces, :default => [] zabbix_attr :profile - zabbix_attr :dns zabbix_attr :status - zabbix_attr :use_ip, :default => true zabbix_attr :monitored, :default => true zabbix_attr :use_ipmi, :default => false zabbix_attr :ipmi_port, :default => 623 @@ -71,11 +81,7 @@ def initialize properties={} self.user_macro_ids = properties[:user_macro_ids] self.user_macros = properties[:user_macros] - end - - def use_ip - return @use_ip if (!@use_ip.nil?) - @use_ip = true + self.interfaces = properties[:interfaces].map { |i| Interface.new i } end def monitored @@ -103,8 +109,12 @@ def use_ipmi def validate raise ValidationError.new("A host must have at least one host group.") if host_group_ids.nil? || host_group_ids.empty? # raise ValidationError.new("A host must have a valid ip address if use_ip is set.") if use_ip && ip == self.class::BLANK_IP - raise ValidationError.new("A host must have an ip address if use_ip is set.") if use_ip && (ip.nil? || ip.empty?) - raise ValidationError.new("A host must have a dns name if use_ip is false.") if !use_ip && dns.nil? + raise ValidationError.new("A host must have at least one interface") if interfaces.empty? + + interfaces.each do |i| + raise ValidationError.new("A host must have an ip address if use_ip is set.") if i.use_ip && (i.ip.nil? || i.ip.empty?) + raise ValidationError.new("A host must have a dns name if use_ip is false.") if !i.use_ip && i.dns.nil? + end raise ValidationError.new("A host must have a ipmi_privilege defined as one of: " + self.class::IPMI_PRIVILEGE_CODES.keys.to_s) if use_ipmi && self.class::IPMI_PRIVILEGE_CODES[ipmi_privilege].nil? raise ValidationError.new("A host must have a ipmi_authtype defined as one of: " + self.class::IPMI_AUTH_CODES.keys.to_s) if use_ipmi && self.class::IPMI_AUTH_CODES[ipmi_authtype].nil? true @@ -124,17 +134,24 @@ def create_params hp[:profile] = profile if profile hp[:profile].delete("hostid") if hp[:profile] && hp[:profile]["hostid"] hp[:status] = (monitored ? 0 : 1) unless monitored.nil? - + # Check to see if use_ip is set, otherwise we will use dns - hp[:useip] = (use_ip == true ? 1 : 0) - - # if we have an IP then use it, otherwise use 0.0.0.0, same goes for the port - hp[:ip] = ip || self.class::BLANK_IP - hp[:port] = port || self.class::DEFAULT_PORT - - # Always allow for a DNS record to exist even if we dont use it to monitor. - hp[:dns] = dns if dns - + hp[:interfaces] = [] + interfaces.each do |i| + res = {} + res[:useip] = (i.use_ip == true ? 1 : 0) + + # if we have an IP then use it, otherwise use 0.0.0.0, same goes for the port + res[:ip] = i.ip || self.class::BLANK_IP + res[:port] = i.port || self.class::DEFAULT_PORT + + # Always allow for a DNS record to exist even if we dont use it to monitor. + res[:dns] = i.dns if i.dns + res[:main] = i.main + res[:type] = i.type + hp[:interfaces] << res + end + hp[:useipmi] = (use_ipmi == true ? 1 : 0) hp[:ipmi_port] = ipmi_port if ipmi_port hp[:ipmi_username] = ipmi_username if ipmi_username @@ -144,7 +161,7 @@ def create_params hp[:ipmi_privilege] = self.class::IPMI_PRIVILEGE_CODES[ipmi_privilege] if ipmi_privilege end end - + def update_params create_params.tap do |cp| cp.delete(:groups) @@ -183,10 +200,11 @@ def self.build host :template_ids => host['parentTemplates'].map { |template| (template['templateid'] || template[id_field]).to_i }, :user_macros => host['macros'].map { |um| UserMacro.new(:host_id => um[id_field].to_i, :id => um['hostmacroid'], :value => um['value'], :macro => um['macro']) }, :profile => host['profile'], - :port => host['port'], - :ip => host['ip'], - :dns => host['dns'], - :use_ip => (host['useip'].to_i == 1), + :interfaces => host['interfaces'].map { |k, i| + {:port => i['port'], + :ip => i['ip'], + :dns => i['dns'], + :use_ip => (i['useip'].to_i == 1)}}, # If the status is '1' then this is an unmonitored host. # Otherwise it's either '0' for monitored and ok or @@ -204,12 +222,8 @@ def self.build host end def self.get_params - case api_version - when '1.4' - super().merge({:selectGroups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :selectMacros => :extend}) - else - super().merge({:select_groups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :select_macros => :extend}) - end + super().merge({:selectGroups => :refer, :selectParentTemplates => :refer, :select_profile => :refer, :selectMacros => :extend, + :selectInterfaces => :extend}) end def self.find_params options={} diff --git a/lib/rubix/models/host_group.rb b/lib/rubix/models/host_group.rb index cd990ae..0ea8080 100644 --- a/lib/rubix/models/host_group.rb +++ b/lib/rubix/models/host_group.rb @@ -37,12 +37,7 @@ def destroy_params end def self.get_params - case api_version - when '1.4' - super().merge(:selectHosts => :refer) - else - super().merge(:select_hosts => :refer) - end + super().merge(:selectHosts => :refer) end def self.find_params options={} diff --git a/lib/rubix/models/template.rb b/lib/rubix/models/template.rb index 81fa4c4..e164a52 100644 --- a/lib/rubix/models/template.rb +++ b/lib/rubix/models/template.rb @@ -52,12 +52,7 @@ def destroy_params end def self.get_params - case api_version - when '1.4' - super().merge(:selectGroups => :refer, :selectHosts => :refer) - else - super().merge(:select_groups => :refer, :select_hosts => :refer) - end + super().merge(:selectGroups => :refer, :selectHosts => :refer) end def self.find_params options={} diff --git a/spec/requests/host_request_spec.rb b/spec/requests/host_request_spec.rb index d0e1d65..7c29e90 100644 --- a/spec/requests/host_request_spec.rb +++ b/spec/requests/host_request_spec.rb @@ -24,21 +24,21 @@ it "returns an empty array when listing with IDs" do Rubix::Host.list([1,2,3]).should == [] end - + it "can be created" do - host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :ip => '123.123.123.123') + host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => [:ip => '123.123.123.123']) host.save.should be_true host.monitored.should be_true - host.use_ip.should be_true - host.ip.should == '123.123.123.123' + host.interfaces.first.use_ip.should be_true + host.interfaces.first.ip.should == '123.123.123.123' end it "can be created with a blank IP" do - host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :ip => '0.0.0.0') + host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => [:ip => '0.0.0.0']) host.save.should be_true host.monitored.should be_true - host.use_ip.should be_true - host.ip.should == '0.0.0.0' + host.interfaces.first.use_ip.should be_true + host.interfaces.first.ip.should == '0.0.0.0' end end @@ -46,7 +46,8 @@ describe "when existing" do before do @host_group_2 = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_2')) - @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :ip => '123.123.123.123')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], + :interfaces => [{:ip => '123.123.123.123'}])) @template_1 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_1', :host_groups => [@host_group_2])) @template_2 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_2', :host_groups => [@host_group_2])) end diff --git a/spec/support/integration_helper.rb b/spec/support/integration_helper.rb index 0643654..632d8e0 100644 --- a/spec/support/integration_helper.rb +++ b/spec/support/integration_helper.rb @@ -16,7 +16,7 @@ def self.setup_integration_tests test_yml_path return end unless connect_to_database - puts "Could not connect to a MySQL database using: #{$RUBIX_MYSQL_CREDENTIALS.inspect}. Integration tests will be skipped." + puts "Could not connect to a database using: #{$CONFIG['postgresql'].inspect}. Integration tests will be skipped." return end unless truncate_all_tables @@ -28,55 +28,56 @@ def self.setup_integration_tests test_yml_path return end unless connect_to_api - puts "Could not connect to Zabbix API using: #{$RUBIX_API_CREDENTIALS.inspect}. Integration tests will be skipped." + puts "Could not connect to Zabbix API using: #{$CONFIG['api']}. Integration tests will be skipped." return end $RUBIX_INTEGRATION = true end - + def self.parse_integration_settings test_yml_path return unless File.exist?(test_yml_path) - + require 'yaml' test_data = YAML.load(open(test_yml_path)) return if test_data['disable_integration_tests'] - - $RUBIX_API_CREDENTIALS = test_data['api'] - $RUBIX_MYSQL_CREDENTIALS = test_data['mysql'] + + $CONFIG = test_data end def self.connect_to_database begin - require 'mysql2' - $RUBIX_MYSQL = Mysql2::Client.new(:host => $RUBIX_MYSQL_CREDENTIALS['host'], :username => $RUBIX_MYSQL_CREDENTIALS['username'], :password => $RUBIX_MYSQL_CREDENTIALS['password'], :database => $RUBIX_MYSQL_CREDENTIALS['database']) + require 'pg' + $CONN = PG::Connection.new(:host => $CONFIG['postgresql']['host'], :user => $CONFIG['postgresql']['username'], + :password => $CONFIG['postgresql']['password'], :dbname => $CONFIG['postgresql']['database'], + :port => $CONFIG['postgresql']['port']) rescue => e - puts "Could not connect to MySQL database: #{e.class} -- #{e.message}" + puts "Could not connect to database: #{e.class} -- #{e.message}" puts e.backtrace false end end # These are the tables we'll truncate in the database. - RUBIX_TABLES_TO_TRUNCATE = %w[actions conditions operations opconditions opmediatypes applications groups hostmacro hosts hosts_groups hosts_profiles hosts_profiles_ext hosts_templates items items_applications profiles triggers trigger_depends history sessions media_type scripts users usrgrp users_groups] + RUBIX_TABLES_TO_TRUNCATE = %w[actions conditions operations opconditions applications groups hostmacro hosts hosts_groups hosts_templates items items_applications profiles triggers trigger_depends history sessions media_type scripts users usrgrp users_groups] def self.truncate_all_tables - return unless $RUBIX_MYSQL + return unless $CONN begin - RUBIX_TABLES_TO_TRUNCATE.each { |table| $RUBIX_MYSQL.query("TRUNCATE TABLE #{table}") } + RUBIX_TABLES_TO_TRUNCATE.each { |table| $CONN.query("TRUNCATE TABLE #{table} CASCADE") } true rescue => e - puts "Could not truncate tables in MySQL: #{e.class} -- #{e.message}" + puts "Could not truncate tables: #{e.class} -- #{e.message}" puts e.backtrace false end end def self.create_integration_test_user_and_group - return unless $RUBIX_MYSQL + return unless $CONN begin - $RUBIX_MYSQL.query(%Q{INSERT INTO users (`alias`, `name`, surname, passwd, type) VALUES ("#{INTEGRATION_USER}", "Rubix", "Spec User", "#{Digest::MD5.hexdigest('rubix')}", 3)}) - $RUBIX_MYSQL.query(%Q{INSERT INTO usrgrp (`name`, api_access) VALUES ("#{INTEGRATION_GROUP}", 1)}) - $RUBIX_MYSQL.query(%Q{INSERT INTO users_groups (usrgrpid, userid) SELECT users.userid, usrgrp.usrgrpid FROM users, usrgrp WHERE users.alias = '#{INTEGRATION_USER}' AND usrgrp.name = '#{INTEGRATION_GROUP}'}) + $CONN.query(%Q{INSERT INTO users (userid, alias, name, surname, passwd, type) VALUES (42, '#{INTEGRATION_USER}', 'Rubix', 'Spec User', '#{Digest::MD5.hexdigest('rubix')}', 3)}) + $CONN.query(%Q{INSERT INTO usrgrp (usrgrpid, name, gui_access) VALUES (42, '#{INTEGRATION_GROUP}', 1)}) + $CONN.query(%Q{INSERT INTO users_groups (id, usrgrpid, userid) SELECT 42, users.userid, usrgrp.usrgrpid FROM users, usrgrp WHERE users.alias = '#{INTEGRATION_USER}' AND usrgrp.name = '#{INTEGRATION_GROUP}'}) true rescue => e puts "Could not create integration user or group: #{e.class} -- #{e.message}" @@ -86,9 +87,9 @@ def self.create_integration_test_user_and_group end def self.connect_to_api - return unless $RUBIX_API_CREDENTIALS + return unless $CONFIG['api'] begin - $RUBIX_API = Rubix::Connection.new($RUBIX_API_CREDENTIALS['url'], INTEGRATION_USER, INTEGRATION_PASSWORD) + $RUBIX_API = Rubix::Connection.new($CONFIG['api'], INTEGRATION_USER, INTEGRATION_PASSWORD) $RUBIX_API.authorize! Rubix.connection = $RUBIX_API rescue => e @@ -145,7 +146,7 @@ def ensure_destroy *objs, &block raise e end end - + def create_history item raise Rubix::Error.new("Not connected to MySQL") unless $RUBIX_MYSQL (1..10).to_a.collect do |i| From 6acc1ae0ded831ea791114cf2b462e233daa4afc Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 15 Jan 2013 23:47:53 +0400 Subject: [PATCH 05/32] Templates fix (but not import) and host group fix --- lib/rubix/models/host_group.rb | 13 ++++++------- lib/rubix/models/template.rb | 3 +-- spec/requests/template_request_spec.rb | 2 -- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/rubix/models/host_group.rb b/lib/rubix/models/host_group.rb index 0ea8080..aa4b61d 100644 --- a/lib/rubix/models/host_group.rb +++ b/lib/rubix/models/host_group.rb @@ -1,5 +1,5 @@ module Rubix - + class HostGroup < Model # @@ -11,17 +11,17 @@ def initialize properties={} self.host_ids = properties[:host_ids] self.hosts = properties[:hosts] end - + zabbix_attr :name, :required => true - + def self.id_field 'groupid' end - + # # == Associations == # - + include Associations::HasManyHosts # @@ -33,7 +33,7 @@ def create_params end def destroy_params - [{id_field => id}] + [id] end def self.get_params @@ -51,6 +51,5 @@ def self.build host_group :host_ids => host_group['hosts'].map { |host_info| host_info['hostid'].to_i } }) end - end end diff --git a/lib/rubix/models/template.rb b/lib/rubix/models/template.rb index e164a52..5e5ff5b 100644 --- a/lib/rubix/models/template.rb +++ b/lib/rubix/models/template.rb @@ -48,7 +48,7 @@ def update_params end def destroy_params - [{id_field => id}] + [id] end def self.get_params @@ -109,6 +109,5 @@ def self.import_options options end end end - end end diff --git a/spec/requests/template_request_spec.rb b/spec/requests/template_request_spec.rb index 0b8bfd5..6b8a0e4 100644 --- a/spec/requests/template_request_spec.rb +++ b/spec/requests/template_request_spec.rb @@ -27,7 +27,6 @@ Rubix::Template.import(File.new(data_path('test_template.xml'))) Rubix::Template.find(:name => 'test').should_not be_nil end - end describe "when existing" do @@ -47,7 +46,6 @@ @template.destroy Rubix::Template.find(:name => 'rubix_spec_template_1').should be_nil end - end end From 962753ec0d996ebcbb34b3529dfd7960ff41e244 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 12:00:29 +0400 Subject: [PATCH 06/32] Move database logic to database_helper, add postgresql and mysql support --- spec/support/database_helper.rb | 57 ++++++++++++++++++++++++++++++ spec/support/integration_helper.rb | 47 ++++-------------------- 2 files changed, 63 insertions(+), 41 deletions(-) create mode 100644 spec/support/database_helper.rb diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb new file mode 100644 index 0000000..a2c300d --- /dev/null +++ b/spec/support/database_helper.rb @@ -0,0 +1,57 @@ +module Rubix + class DatabaseHelper + + attr_accessor :result + + def initialize config + begin + if config['postgresql'] + require 'pg' + @conn = PG::Connection.new(:host => config['postgresql']['host'], :user => config['postgresql']['username'], + :password => config['postgresql']['password'], :dbname => config['postgresql']['database'], + :port => config['postgresql']['port']) + elsif config['mysql'] + require 'mysql2' + @conn = Mysql2::Client.new(:host => config['mysql']['host'], :username => config['mysql']['username'], :password => config['mysql']['password'], + :database => config['mysql']['database']) + end + @result = true + rescue => e + puts "Could not connect to database: #{e.class} -- #{e.message}" + puts e.backtrace + @result = false + end + end + + def truncate_all_tables + return unless result + begin + %w[actions graphs triggers items applications hosts].each do |table| + @conn.query("DELETE FROM #{table}") + end + @conn.query('DELETE FROM groups WHERE internal != 1') + @conn.query(%Q[DELETE FROM users WHERE alias != 'Admin' AND 'alias' != 'guest']) + @conn.query('DELETE FROM usrgrp WHERE usrgrpid = 42') + true + rescue => e + puts "Could not truncate tables: #{e.class} -- #{e.message}" + puts e.backtrace + false + end + end + + def create_integration_test_user_and_group(user, group, password) + return unless result + begin + @conn.query(%Q{INSERT INTO users (userid, alias, name, surname, passwd, type) VALUES (42, '#{user}', 'Rubix', 'Spec User', '#{Digest::MD5.hexdigest(password)}', 3)}) + @conn.query(%Q{INSERT INTO usrgrp (usrgrpid, name, gui_access) VALUES (42, '#{group}', 1)}) + @conn.query(%Q{INSERT INTO users_groups (id, usrgrpid, userid) SELECT 42, users.userid, usrgrp.usrgrpid FROM users, usrgrp WHERE users.alias = '#{user}' AND usrgrp.name = '#{group}'}) + true + rescue => e + puts "Could not create integration user or group: #{e.class} -- #{e.message}" + puts e.backtrace + false + end + end + end +end diff --git a/spec/support/integration_helper.rb b/spec/support/integration_helper.rb index 5531ad1..1892c29 100644 --- a/spec/support/integration_helper.rb +++ b/spec/support/integration_helper.rb @@ -45,51 +45,16 @@ def self.parse_integration_settings test_yml_path end def self.connect_to_database - begin - require 'pg' - $CONN = PG::Connection.new(:host => $CONFIG['postgresql']['host'], :user => $CONFIG['postgresql']['username'], - :password => $CONFIG['postgresql']['password'], :dbname => $CONFIG['postgresql']['database'], - :port => $CONFIG['postgresql']['port']) - rescue => e - puts "Could not connect to database: #{e.class} -- #{e.message}" - puts e.backtrace - false - end + $CONN = DatabaseHelper.new $CONFIG + $CONN.result end - + def self.truncate_all_tables - return unless $CONN - begin - %w[actions graphs triggers items applications hosts].each do |table| - $RUBIX_MYSQL.query("DELETE FROM #{table}") - end - $RUBIX_MYSQL.query('DELETE FROM groups WHERE `internal` != 1') - $RUBIX_MYSQL.query('DELETE FROM users WHERE `alias` != "Admin" AND `alias` != "guest"') - true - rescue => e - puts "Could not truncate tables: #{e.class} -- #{e.message}" - puts e.backtrace - false - end + $CONN.truncate_all_tables end def self.create_integration_test_user_and_group - return unless $CONN - begin - $CONN.query(%Q{INSERT INTO users (userid, alias, name, surname, passwd, type) VALUES (42, '#{INTEGRATION_USER}', 'Rubix', 'Spec User', '#{Digest::MD5.hexdigest('rubix')}', 3)}) - $CONN.query(%Q{INSERT INTO usrgrp (usrgrpid, name, gui_access) VALUES (42, '#{INTEGRATION_GROUP}', 1)}) - $CONN.query(%Q{INSERT INTO users_groups (id, usrgrpid, userid) SELECT 42, users.userid, usrgrp.usrgrpid FROM users, usrgrp WHERE users.alias = '#{INTEGRATION_USER}' AND usrgrp.name = '#{INTEGRATION_GROUP}'}) -=begin - $RUBIX_MYSQL.query(%Q{INSERT INTO users (`alias`, `name`, surname, passwd, type) VALUES ("#{INTEGRATION_USER}", "Rubix", "Spec User", "#{Digest::MD5.hexdigest('rubix')}", 3)}) - # $RUBIX_MYSQL.query(%Q{INSERT INTO usrgrp (`name`, api_access) VALUES ("#{INTEGRATION_GROUP}", 1)}) - $RUBIX_MYSQL.query(%Q{INSERT INTO users_groups (usrgrpid, userid) SELECT users.userid, usrgrp.usrgrpid FROM users, usrgrp WHERE users.alias = '#{INTEGRATION_USER}' AND usrgrp.name = '#{INTEGRATION_GROUP}'}) -=end - true - rescue => e - puts "Could not create integration user or group: #{e.class} -- #{e.message}" - puts e.backtrace - false - end + $CONN.create_integration_test_user_and_group(INTEGRATION_USER, INTEGRATION_GROUP, INTEGRATION_PASSWORD) end def self.connect_to_api @@ -107,7 +72,7 @@ def self.connect_to_api def integration_test if $RUBIX_INTEGRATION - raise Rubix::Error.new("Could not truncate tables in MySQL.") unless IntegrationHelper.truncate_all_tables + raise Rubix::Error.new("Could not truncate tables.") unless IntegrationHelper.truncate_all_tables raise Rubix::Error.new("Could not create integration user or group.") unless IntegrationHelper.create_integration_test_user_and_group raise Rubix::Error.new("Could not connect to Zabbixi API.") unless IntegrationHelper.connect_to_api else From 4ae893a4a9a33ceb5b12b374a3a6143c71c9bb1b Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 12:41:12 +0400 Subject: [PATCH 07/32] Host specs fixed --- lib/rubix/models/host.rb | 18 +++++++++++++++--- lib/rubix/models/interface.rb | 4 +--- spec/requests/host_request_spec.rb | 16 +++++++--------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/lib/rubix/models/host.rb b/lib/rubix/models/host.rb index 71a86d8..0452a82 100644 --- a/lib/rubix/models/host.rb +++ b/lib/rubix/models/host.rb @@ -72,7 +72,19 @@ class Host < Model zabbix_attr :snmp_error zabbix_attr :snmp_errors_from zabbix_attr :last_access - + + def monitored + @status == :monitored + end + + def monitored= value + if value + @status = :monitored + else + @status = :not_monitored + end + end + def initialize properties={} super(properties) @@ -84,10 +96,10 @@ def initialize properties={} self.interface_ids = properties[:interface_ids] self.interfaces = properties[:interfaces] - + self.user_macro_ids = properties[:user_macro_ids] self.user_macros = properties[:user_macros] - + self.inventory = properties[:inventory] end diff --git a/lib/rubix/models/interface.rb b/lib/rubix/models/interface.rb index dea51bc..f0b2183 100644 --- a/lib/rubix/models/interface.rb +++ b/lib/rubix/models/interface.rb @@ -58,17 +58,15 @@ def create_params end def self.build interface - p interface new({ :id => interface[id_field].to_i, :host_id => interface['hostid'], :main => (interface['main'].to_i == 1), :type => self::TYPE_NAMES[interface['type'].to_i], - :use_ip => (interface['useip'].to_i == 1), + :use_ip => interface['useip'], :dns => interface['dns'], :ip => interface['ip'], }) end - end end diff --git a/spec/requests/host_request_spec.rb b/spec/requests/host_request_spec.rb index d806ffb..576d1d7 100644 --- a/spec/requests/host_request_spec.rb +++ b/spec/requests/host_request_spec.rb @@ -26,7 +26,7 @@ end it "can be created" do - host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => [{:ip => '123.123.123.123'}]) + host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => [{'ip' => '123.123.123.123', 'main' => '1'}]) host.save.should be_true host.monitored.should be_true host.interfaces.first.use_ip.should be_true @@ -34,20 +34,19 @@ end it "can be created with a blank IP" do - host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => [:ip => '0.0.0.0']) + host = Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], :interfaces => ['ip' => '0.0.0.0', 'main' => '1']) host.save.should be_true host.monitored.should be_true host.interfaces.first.use_ip.should be_true host.interfaces.first.ip.should == '0.0.0.0' end - end describe "when existing" do before do @host_group_2 = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_2')) @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group_1], - :interfaces => [{:ip => '123.123.123.123'}])) + :interfaces => [{'ip' => '123.123.123.123', 'main' => '1'}])) @template_1 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_1', :host_groups => [@host_group_2])) @template_2 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_2', :host_groups => [@host_group_2])) end @@ -76,7 +75,7 @@ it "can change its host groups" do @host.host_groups = [@host_group_1, @host_group_2] @host.save - + new_host = Rubix::Host.find(:name => 'rubix_spec_host_1') new_host.should_not be_nil new_host.host_groups.size.should == 2 @@ -86,17 +85,17 @@ it "can change its monitoring status" do @host.monitored = false @host.save - + new_host = Rubix::Host.find(:name => 'rubix_spec_host_1') new_host.should_not be_nil new_host.monitored.should be_false new_host.status.should == :not_monitored end - + it "can change its templates" do @host.templates = [@template_1, @template_2] @host.save - + new_host = Rubix::Host.find(:name => 'rubix_spec_host_1') new_host.should_not be_nil new_host.templates.size.should == 2 @@ -109,5 +108,4 @@ end end - end From 45bde26c0d4d542f6f15b1cb62c12cf395addb78 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 12:42:33 +0400 Subject: [PATCH 08/32] Application spec fixed --- spec/requests/application_request_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/requests/application_request_spec.rb b/spec/requests/application_request_spec.rb index 46e989e..f92efa7 100644 --- a/spec/requests/application_request_spec.rb +++ b/spec/requests/application_request_spec.rb @@ -5,7 +5,7 @@ before do integration_test @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) - @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :ip => '123.123.123.123')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => '1'])) end after do From 288769aac5dca87cd034ba10f957bfb3e0c997e3 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 13:14:37 +0400 Subject: [PATCH 09/32] Connection spec fix --- lib/rubix/associations/has_many_user_groups.rb | 2 +- lib/rubix/models/action.rb | 2 +- lib/rubix/models/user.rb | 3 ++- spec/requests/action_request_spec.rb | 2 +- spec/requests/connection_request_spec.rb | 6 +++--- spec/support/database_helper.rb | 3 +-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/rubix/associations/has_many_user_groups.rb b/lib/rubix/associations/has_many_user_groups.rb index 4854e17..d2ad67f 100644 --- a/lib/rubix/associations/has_many_user_groups.rb +++ b/lib/rubix/associations/has_many_user_groups.rb @@ -21,7 +21,7 @@ def user_group_ids= ugids def user_group_ids return @user_group_ids if @user_group_ids - return unless @user_groups + return [] unless @user_groups @user_group_ids = @user_groups.map(&:id) end diff --git a/lib/rubix/models/action.rb b/lib/rubix/models/action.rb index 9527119..959890c 100644 --- a/lib/rubix/models/action.rb +++ b/lib/rubix/models/action.rb @@ -21,7 +21,7 @@ class Action < Model zabbix_attr :name, :required => true zabbix_attr :event_source, :default => :triggers, :required => true - zabbix_attr :escalation_time, :default => 0 + zabbix_attr :escalation_time, :default => 60 zabbix_attr :enabled, :default => true zabbix_attr :message_subject, :default => MESSAGE_SUBJECT zabbix_attr :message_body, :default => MESSAGE_BODY diff --git a/lib/rubix/models/user.rb b/lib/rubix/models/user.rb index b155611..5ce2f9e 100644 --- a/lib/rubix/models/user.rb +++ b/lib/rubix/models/user.rb @@ -85,7 +85,8 @@ def create_params :refresh => refresh_period, :type => self.class::TYPE_CODES[type], :theme => theme, - :rows_per_page => rows_per_page + :rows_per_page => rows_per_page, + :usrgrps => user_group_ids.map { |id| {'usrgrpid' => id} } }.tap do |cp| cp[:passwd] = password if password && (!password.empty?) diff --git a/spec/requests/action_request_spec.rb b/spec/requests/action_request_spec.rb index 99a1e05..3909ea7 100644 --- a/spec/requests/action_request_spec.rb +++ b/spec/requests/action_request_spec.rb @@ -5,7 +5,7 @@ before do integration_test @user_group = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) - @user = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix', :last_name => 'user', :password => 'pass')) + @user = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix', :last_name => 'user', :password => 'pass', :user_groups => [@user_group])) end after do diff --git a/spec/requests/connection_request_spec.rb b/spec/requests/connection_request_spec.rb index e832185..6515fb5 100644 --- a/spec/requests/connection_request_spec.rb +++ b/spec/requests/connection_request_spec.rb @@ -11,7 +11,7 @@ end it "can perform an authorized GET request to the homepage" do - response = Rubix.connection.web_request("GET", "/") + response = Rubix.connection.web_request("GET", "/dashboard.php") response.should_not be_nil response.code.to_i.should == 200 response.body.should_not include('guest') @@ -19,7 +19,7 @@ end it "can perform an authorized POST request to the homepage" do - response = Rubix.connection.web_request("POST", "/", :foo => 'bar', :baz => 'buzz') + response = Rubix.connection.web_request("POST", "/dashboard.php", :foo => 'bar', :baz => 'buzz') response.should_not be_nil response.code.to_i.should == 200 response.body.should_not include('guest') @@ -27,7 +27,7 @@ end it "can perform an authorized multipart POST request to the homepage" do - response = Rubix.connection.web_request("POST", "/", :foo => File.new(data_path('test_template.xml'))) + response = Rubix.connection.web_request("POST", "/dashboard.php", :foo => File.new(data_path('test_template.xml'))) response.should_not be_nil response.code.to_i.should == 200 response.body.should_not include('guest') diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb index a2c300d..63db81f 100644 --- a/spec/support/database_helper.rb +++ b/spec/support/database_helper.rb @@ -26,12 +26,11 @@ def initialize config def truncate_all_tables return unless result begin - %w[actions graphs triggers items applications hosts].each do |table| + %w[actions graphs triggers items applications hosts usrgrp].each do |table| @conn.query("DELETE FROM #{table}") end @conn.query('DELETE FROM groups WHERE internal != 1') @conn.query(%Q[DELETE FROM users WHERE alias != 'Admin' AND 'alias' != 'guest']) - @conn.query('DELETE FROM usrgrp WHERE usrgrpid = 42') true rescue => e puts "Could not truncate tables: #{e.class} -- #{e.message}" From 13a94580759c84f53bc6800c84daccbf141b2b29 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 14:14:03 +0400 Subject: [PATCH 10/32] Item spec fixed --- lib/rubix/associations.rb | 1 + .../associations/belongs_to_interface.rb | 32 +++++++++++++++++++ lib/rubix/models/item.rb | 10 +++++- lib/rubix/models/model.rb | 6 ++-- spec/requests/interface_request_spec.rb | 4 +-- spec/requests/item_request_spec.rb | 14 +++++--- 6 files changed, 57 insertions(+), 10 deletions(-) create mode 100644 lib/rubix/associations/belongs_to_interface.rb diff --git a/lib/rubix/associations.rb b/lib/rubix/associations.rb index 3934bc6..09d8202 100644 --- a/lib/rubix/associations.rb +++ b/lib/rubix/associations.rb @@ -20,6 +20,7 @@ module Associations autoload :BelongsToUser, 'rubix/associations/belongs_to_user' autoload :BelongsToUserGroup, 'rubix/associations/belongs_to_user_group' autoload :BelongsToMediaType, 'rubix/associations/belongs_to_media_type' + autoload :BelongsToInterface, 'rubix/associations/belongs_to_interface' end end diff --git a/lib/rubix/associations/belongs_to_interface.rb b/lib/rubix/associations/belongs_to_interface.rb new file mode 100644 index 0000000..c36de39 --- /dev/null +++ b/lib/rubix/associations/belongs_to_interface.rb @@ -0,0 +1,32 @@ +module Rubix + module Associations + + module BelongsToInterface + + def interface= i + return unless i + @interface = i + @interface_id = i.id + end + + def interface + return @interface if @host + return unless @interface_id + @interface = Interface.find(:id => @host_id) + end + + def interface_id= hid + return unless hid + @interface_id = hid + end + + def interface_id + return @interface_id if @host_id + return unless @interface + @interface_id = @host.id + end + + end + end +end + diff --git a/lib/rubix/models/item.rb b/lib/rubix/models/item.rb index 472be7a..4008312 100644 --- a/lib/rubix/models/item.rb +++ b/lib/rubix/models/item.rb @@ -86,13 +86,17 @@ def self.value_code_from_value value zabbix_attr :history zabbix_attr :trends zabbix_attr :status - zabbix_attr :frequency + zabbix_attr :frequency, :required => true, :default => 60 + zabbix_attr :name, :required => true def initialize properties={} super(properties) self.host = properties[:host] self.host_id = properties[:host_id] + self.interface = properties[:interface] + self.interface_id = properties[:interface_id] + self.template = properties[:template] self.template_id = properties[:template_id] @@ -109,6 +113,7 @@ def resource_name # include Associations::BelongsToHost + include Associations::BelongsToInterface include Associations::BelongsToTemplate include Associations::HasManyApplications @@ -119,6 +124,8 @@ def resource_name def create_params { :hostid => host_id, + :interfaceid => interface_id, + :name => name, :description => (description || 'Unknown'), :type => self.class::TYPE_CODES[type], :key_ => key, @@ -157,6 +164,7 @@ def self.find_params options={} def self.build item new({ :id => item[id_field].to_i, + :name => item['name'], :host_id => item['hostid'].to_i, :description => item['description'], :type => TYPE_NAMES[item['type'].to_i], diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index 5355677..9762a37 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -142,7 +142,8 @@ def save # @return [true, false] def validate self.class.properties.each_pair do |property, options| - raise ValidationError.new("A #{self.class.resource_name} must have a #{property}") if options[:required] && (self.send(property).nil? || self.send(property).empty?) + property_value = self.send property + raise ValidationError.new("A #{self.class.resource_name} must have a #{property}") if options[:required] && (property_value.nil? || (!property_value.is_a?(Fixnum) && property_value.empty?)) end true end @@ -273,7 +274,8 @@ def destroy return false unless before_destroy response = destroy_request case - when response.has_data? && response.result.values.first.first.to_i == id + # Zabbix 2.0.4 returns "result":{"itemids":{"22":22}} on item.delete + when response.has_data? && (((tmp = response.result.values.first.first).is_a?(Array) && tmp.first.to_i == id ) || response.result.values.first.first.to_i == id) info("Destroyed Zabbix #{resource_name}") true when response.zabbix_error? && response.error_message =~ /does not exist/i diff --git a/spec/requests/interface_request_spec.rb b/spec/requests/interface_request_spec.rb index eb99e42..67b7206 100644 --- a/spec/requests/interface_request_spec.rb +++ b/spec/requests/interface_request_spec.rb @@ -5,7 +5,7 @@ before do integration_test @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) - @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => [{ :ip => '123.123.123.123'}])) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => [{ 'ip' => '123.123.123.123', 'main' => 1 }])) end after do @@ -13,7 +13,7 @@ end it "can modify an interface" do - @host.interfaces = [{:ip => '100.100.100.100'}] + @host.interfaces = [{'ip' => '100.100.100.100', 'main' => 1}] @host.save h = Rubix::Host.find(:id => @host.id) diff --git a/spec/requests/item_request_spec.rb b/spec/requests/item_request_spec.rb index 721720a..0b3dacb 100644 --- a/spec/requests/item_request_spec.rb +++ b/spec/requests/item_request_spec.rb @@ -5,8 +5,10 @@ before do integration_test @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) - @host_1 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :ip => '123.123.123.123')) - @host_2 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_2', :host_groups => [@host_group], :ip => '123.123.123.124')) + @host_1 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host_1 = Rubix::Host.find(:id => @host_1.id) # reload interfaces with id + @host_2 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_2', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host_2 = Rubix::Host.find(:id => @host_2.id) # reload interfaces with id @app_1 = ensure_save(Rubix::Application.new(:name => 'rubix_spec_app_1', :host_id => @host_1.id)) end @@ -21,7 +23,7 @@ end it "can be created" do - item = Rubix::Item.new(:key => 'rubix.spec1', :description => 'rubix item description 1', :host_id => @host_1.id, :value_type => :character, :applications => [@app_1], :units => 'B') + item = Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix item description 1', :host_id => @host_1.id, :interface_id => @host_1.interfaces.first.id, :value_type => :character, :applications => [@app_1], :units => 'B') item.save.should be_true item.host.name.should == @host_1.name item.applications.map(&:name).should include(@app_1.name) @@ -32,12 +34,13 @@ describe "when existing" do before do - @item = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :description => 'rubix item description 1', :host_id => @host_1.id, :value_type => :character, :applications => [@app_1], :units => 'B')) + @item = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix item description 1', :host_id => @host_1.id, :interface_id => @host_1.interfaces.first.id, :value_type => :character, :applications => [@app_1], :units => 'B')) end it "can have its host, application, and properties updated" do + pending # now we can't change host without change interface first @item.key = 'rubix.spec2' - @item.description = 'rubix item description 2' + @item.name = 'rubix item description 2' @item.type = :external @item.value_type = :unsigned_int @item.data_type = :octal @@ -47,6 +50,7 @@ @item.frequency = 31 @item.multiply_by = 0.1 @item.host_id = @host_2.id + @item.interface_id = @host_2.interfaces.first.id @item.units = 'MB' @item.save.should be_true From 5a4f71e5cf13ffd2da19bd2e42a1d266d13bf289 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 16 Jan 2013 15:37:28 +0400 Subject: [PATCH 11/32] Fix users spec and response and connection specs --- lib/rubix/models/user.rb | 6 +++++- spec/requests/user_request_spec.rb | 7 ++++--- spec/rubix/connection_spec.rb | 1 + spec/rubix/response_spec.rb | 1 + spec/support/database_helper.rb | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/lib/rubix/models/user.rb b/lib/rubix/models/user.rb index 5ce2f9e..8168be1 100644 --- a/lib/rubix/models/user.rb +++ b/lib/rubix/models/user.rb @@ -145,6 +145,10 @@ def self.get_params def self.find_params options={} get_params.merge(:filter => {:alias => options[:username], id_field => options[:id]}) end - + + def destroy_params + [id_field => id] + end + end end diff --git a/spec/requests/user_request_spec.rb b/spec/requests/user_request_spec.rb index cd7391d..2966e7c 100644 --- a/spec/requests/user_request_spec.rb +++ b/spec/requests/user_request_spec.rb @@ -4,6 +4,7 @@ before do integration_test + @user_group = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) end after do @@ -17,7 +18,7 @@ end it "can be created" do - hg = Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1') + hg = Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1', :user_groups => [@user_group]) hg.save.should be_true end @@ -26,7 +27,7 @@ describe "when existing" do before do - @u = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1')) + @u = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1', :user_groups => [@user_group])) end it "can be found" do @@ -75,7 +76,7 @@ end it "can add media to a user when creating" do - Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1', :media => @media_params).save.should be_true + Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1', :media => @media_params, :user_groups => [@user_group]).save.should be_true # FIXME no facility to fetch media!! end diff --git a/spec/rubix/connection_spec.rb b/spec/rubix/connection_spec.rb index ed55b34..21b5b63 100644 --- a/spec/rubix/connection_spec.rb +++ b/spec/rubix/connection_spec.rb @@ -18,6 +18,7 @@ @mock_response.stub!(:body).and_return(@blah_response) @connection = Rubix::Connection.new('localhost/api.php', 'username', 'password') + @connection.stub!(:api_version).and_return(Rubix::SERVER_VERSION) end describe "sending API requests" do diff --git a/spec/rubix/response_spec.rb b/spec/rubix/response_spec.rb index 65499a5..c09910e 100644 --- a/spec/rubix/response_spec.rb +++ b/spec/rubix/response_spec.rb @@ -1,4 +1,5 @@ require 'spec_helper' +require 'json' describe Rubix::Response do diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb index 63db81f..2ae0e28 100644 --- a/spec/support/database_helper.rb +++ b/spec/support/database_helper.rb @@ -26,7 +26,7 @@ def initialize config def truncate_all_tables return unless result begin - %w[actions graphs triggers items applications hosts usrgrp].each do |table| + %w[actions graphs triggers items applications hosts usrgrp media_type].each do |table| @conn.query("DELETE FROM #{table}") end @conn.query('DELETE FROM groups WHERE internal != 1') From 8a80f3bd2fd0cbbff977199a6ea3da7efef9d012 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 17 Jan 2013 13:09:13 +0400 Subject: [PATCH 12/32] Fix trigger and user_group specs --- lib/rubix/models/trigger.rb | 5 ++--- lib/rubix/models/user_group.rb | 12 ++++-------- spec/requests/trigger_request_spec.rb | 14 ++++++++------ spec/requests/user_group_request_spec.rb | 13 ++++++------- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/lib/rubix/models/trigger.rb b/lib/rubix/models/trigger.rb index e8a0d80..bb564a3 100644 --- a/lib/rubix/models/trigger.rb +++ b/lib/rubix/models/trigger.rb @@ -75,7 +75,6 @@ def resource_name def create_params { - :templateid => (template_id || host_id), :description => (description || 'Unknown'), :expression => expression, :priority => self.class::PRIORITY_CODES[priority], @@ -86,7 +85,7 @@ def create_params end def self.get_params - super().merge(:select_items => :refer) + super().merge(:selectItems => :refer) end def self.find_params options={} @@ -115,7 +114,7 @@ def self.build trigger :status => STATUS_NAMES[trigger['status'].to_i], :priority => PRIORITY_NAMES[trigger['priority'].to_i], :item_ids => (trigger['items'] || []).map { |item| item['itemid'].to_i } - }.merge(host_or_template_params_from_id(trigger['templateid'].to_i))) + }.merge(host_or_template_params_from_id(trigger['hosts'].first['hostid'].to_i))) end def self.host_or_template_params_from_id id diff --git a/lib/rubix/models/user_group.rb b/lib/rubix/models/user_group.rb index 0a49624..60300bb 100644 --- a/lib/rubix/models/user_group.rb +++ b/lib/rubix/models/user_group.rb @@ -15,10 +15,9 @@ class UserGroup < Model # zabbix_attr :name - zabbix_attr :api_access, :default => false zabbix_attr :debug_mode, :default => false zabbix_attr :banned, :default => false - zabbix_attr :gui_access, :default => :default + zabbix_attr :api_access, :default => :default def initialize properties={} super(properties) @@ -43,9 +42,8 @@ def self.id_field def create_params { :name => name, - :gui_access => self.class::GUI_ACCESS_CODES[gui_access], + :gui_access => self.class::GUI_ACCESS_CODES[api_access], :users_status => (banned ? 1 : 0), - :api_access => (api_access ? 1 : 0), :debug_mode => (debug_mode ? 1 : 0) } end @@ -70,7 +68,7 @@ def update_users end def self.get_params - super().merge(:select_users => :refer) + super().merge(:selectUsers => :refer) end def self.find_params options={} @@ -81,13 +79,11 @@ def self.build user_group new({ :id => user_group[id_field].to_i, :name => user_group['name'], - :gui_access => self::GUI_ACCESS_NAMES[user_group['gui_access'].to_i], + :api_access => self::GUI_ACCESS_NAMES[user_group['gui_access'].to_i], :banned => (user_group['users_status'].to_i == 1), - :api_access => (user_group['api_access'].to_i == 1), :debug_mode => (user_group['debug_mode'].to_i == 1), :user_ids => user_group['users'].map { |user_info| user_info['userid'].to_i } }) end - end end diff --git a/spec/requests/trigger_request_spec.rb b/spec/requests/trigger_request_spec.rb index 1bef741..75ad658 100644 --- a/spec/requests/trigger_request_spec.rb +++ b/spec/requests/trigger_request_spec.rb @@ -8,13 +8,15 @@ @template_1 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_1', :host_groups => [@host_group])) @template_2 = ensure_save(Rubix::Template.new(:name => 'rubix_spec_template_2', :host_groups => [@host_group])) - @template_item_1 = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :description => 'rubix template item description 1', :host_id => @template_1.id, :value_type => :character)) - @template_item_2 = ensure_save(Rubix::Item.new(:key => 'rubix.spec2', :description => 'rubix template item description 2', :host_id => @template_2.id, :value_type => :character)) + @template_item_1 = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix template item description 1', :host_id => @template_1.id, :value_type => :character)) + @template_item_2 = ensure_save(Rubix::Item.new(:key => 'rubix.spec2', :name => 'rubix template item description 2', :host_id => @template_2.id, :value_type => :character)) - @host_1 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :ip => '123.123.123.123')) - @host_2 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_2', :host_groups => [@host_group], :ip => '123.123.123.124')) - @host_item_1 = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :description => 'rubix host item description 1', :host_id => @host_1.id, :value_type => :character)) - @host_item_2 = ensure_save(Rubix::Item.new(:key => 'rubix.spec2', :description => 'rubix host item description 2', :host_id => @host_2.id, :value_type => :character)) + @host_1 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host_1 = Rubix::Host.find(:id => @host_1.id) # reload for interfaces + @host_2 = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_2', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host_2 = Rubix::Host.find(:id => @host_2.id) # reload for interfaces + @host_item_1 = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix host item description 1', :host_id => @host_1.id, :interface_id => @host_1.interfaces.first.id, :value_type => :character)) + @host_item_2 = ensure_save(Rubix::Item.new(:key => 'rubix.spec2', :name => 'rubix host item description 2', :host_id => @host_2.id, :interface_id => @host_2.interfaces.first.id, :value_type => :character)) end after do diff --git a/spec/requests/user_group_request_spec.rb b/spec/requests/user_group_request_spec.rb index 8972130..11b1a8e 100644 --- a/spec/requests/user_group_request_spec.rb +++ b/spec/requests/user_group_request_spec.rb @@ -36,17 +36,15 @@ it "can have its name and settings changed" do @ug.name = 'rubix_spec_user_group_2' @ug.banned = true - @ug.api_access = true + @ug.api_access = :disabled @ug.debug_mode = true - @ug.gui_access = :disabled @ug.save Rubix::UserGroup.find(:name => 'rubix_spec_user_group_1').should be_nil nug = Rubix::UserGroup.find(:name => 'rubix_spec_user_group_2') nug.should_not be_nil nug.name.should == 'rubix_spec_user_group_2' nug.banned.should == true - nug.api_access.should == true - nug.gui_access.should == :disabled + nug.api_access.should == :disabled nug.debug_mode.should == true end @@ -59,9 +57,10 @@ describe "linking users to user groups" do before do - @u1 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1')) - @u2 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_2', :first_name => 'rubix2', :last_name => 'user2', :password => 'pass2')) - @u3 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_3', :first_name => 'rubix3', :last_name => 'user3', :password => 'pass3')) + @ug = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) + @u1 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix1', :last_name => 'user1', :password => 'pass1', :user_groups => [@ug])) + @u2 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_2', :first_name => 'rubix2', :last_name => 'user2', :password => 'pass2', :user_groups => [@ug])) + @u3 = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_3', :first_name => 'rubix3', :last_name => 'user3', :password => 'pass3', :user_groups => [@ug])) end it "can add users on create" do From eb7a3eaae6c1fcb6b143764f84baecb023640be4 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 17 Jan 2013 13:19:27 +0400 Subject: [PATCH 13/32] Fix spec from user macro --- lib/rubix/models/user_macro.rb | 16 ++-------------- spec/requests/user_macro_request_spec.rb | 5 ++--- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/lib/rubix/models/user_macro.rb b/lib/rubix/models/user_macro.rb index c23eef5..8891d1b 100644 --- a/lib/rubix/models/user_macro.rb +++ b/lib/rubix/models/user_macro.rb @@ -53,20 +53,8 @@ def resource_name # == Requests == # - def mass_add_params - { :macros => [{:macro => macro_name, :value => value}], :hosts => [{:hostid => host_id}] } - end - - def create_request - request('usermacro.massAdd', mass_add_params) - end - - def update_request - request('usermacro.massUpdate', mass_add_params) - end - - def destroy_request - request('usermacro.massRemove', :hostids => [host_id], :macros => [macro_name]) + def create_params + {:macro => macro_name, :value => value, :hostid => host_id} end def self.find_params options={} diff --git a/spec/requests/user_macro_request_spec.rb b/spec/requests/user_macro_request_spec.rb index fad1888..9059104 100644 --- a/spec/requests/user_macro_request_spec.rb +++ b/spec/requests/user_macro_request_spec.rb @@ -5,7 +5,7 @@ before do integration_test @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) - @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :ip => '123.123.123.123')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) end after do @@ -15,7 +15,7 @@ describe "when not existing" do it "returns nil on find" do - Rubix::UserMacro.find(:name => 'rubix_spec_macro_1', :host_id => @host.id).should be_nil + Rubix::UserMacro.find(:name => 'rubix_spec_macro_1', :host_id => @host.id).should be_nil end it "can be created" do @@ -44,6 +44,5 @@ @macro.destroy Rubix::UserMacro.find(:name => 'rubix_spec_macro_1', :host_id => @host.id).should be_nil end - end end From 4170becc6392fb4da5a3a0a40b07e34fb8e2d159 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 17 Jan 2013 14:02:10 +0400 Subject: [PATCH 14/32] Fix time series specs --- spec/requests/action_request_spec.rb | 2 ++ spec/requests/time_series_request_spec.rb | 5 +++-- spec/support/database_helper.rb | 11 ++++++++++- spec/support/integration_helper.rb | 7 +------ 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/spec/requests/action_request_spec.rb b/spec/requests/action_request_spec.rb index 3909ea7..0567721 100644 --- a/spec/requests/action_request_spec.rb +++ b/spec/requests/action_request_spec.rb @@ -4,6 +4,8 @@ before do integration_test + Rubix.logger = Logger.new STDOUT + Rubix.logger.level = Logger::DEBUG @user_group = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) @user = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix', :last_name => 'user', :password => 'pass', :user_groups => [@user_group])) end diff --git a/spec/requests/time_series_request_spec.rb b/spec/requests/time_series_request_spec.rb index 1a101dc..7b39a13 100644 --- a/spec/requests/time_series_request_spec.rb +++ b/spec/requests/time_series_request_spec.rb @@ -5,7 +5,8 @@ before do integration_test @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) - @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :ip => '123.123.123.123')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host = Rubix::Host.find(:id => @host.id) # FIXME reread host interfaces after creation end after do @@ -44,7 +45,7 @@ describe "when the item exists" do before do - @item = ensure_save(Rubix::Item.new(:host_id => @host.id, :key => 'foo.bar.baz', :value_type => :unsigned_int, :description => "rubix item description")) + @item = ensure_save(Rubix::Item.new(:host_id => @host.id, :interface_id => @host.interfaces.first.id, :key => 'foo.bar.baz', :value_type => :unsigned_int, :name => "rubix item description")) @history = create_history(@item) end diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb index 2ae0e28..d3765dc 100644 --- a/spec/support/database_helper.rb +++ b/spec/support/database_helper.rb @@ -26,7 +26,7 @@ def initialize config def truncate_all_tables return unless result begin - %w[actions graphs triggers items applications hosts usrgrp media_type].each do |table| + %w[actions graphs triggers items applications hosts usrgrp media_type scripts].each do |table| @conn.query("DELETE FROM #{table}") end @conn.query('DELETE FROM groups WHERE internal != 1') @@ -52,5 +52,14 @@ def create_integration_test_user_and_group(user, group, password) false end end + + def create_history item + raise Rubix::Error.new("Not connected to database") unless result + (1..10).to_a.collect do |i| + history = { "itemid" => item.id.to_s, "clock" => (Time.now.to_i - 5*i).to_s, "value" => rand(100).to_s, "ns" => "0" } + @conn.query("INSERT INTO history_uint (#{history.keys.join(', ')}) VALUES (#{history.values.join(', ')})") + history + end + end end end diff --git a/spec/support/integration_helper.rb b/spec/support/integration_helper.rb index 1892c29..459079c 100644 --- a/spec/support/integration_helper.rb +++ b/spec/support/integration_helper.rb @@ -119,12 +119,7 @@ def ensure_destroy *objs, &block end def create_history item - raise Rubix::Error.new("Not connected to MySQL") unless $RUBIX_MYSQL - (1..10).to_a.collect do |i| - history = { "itemid" => item.id.to_s, "clock" => (Time.now.to_i - 5*i).to_s, "value" => rand(100).to_s } - $RUBIX_MYSQL.query("INSERT INTO history_uint (#{history.keys.join(', ')}) VALUES (#{history.values.join(', ')})") - history - end + $CONN.create_history item end def truncate_all_tables From 45d4c622fd5ee61c7fd336748b9f6a0b1cff9844 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 22 Jan 2013 16:47:56 +0400 Subject: [PATCH 15/32] Fix template.import --- lib/rubix/models/template.rb | 24 +++++++++++++----------- spec/support/database_helper.rb | 3 ++- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/rubix/models/template.rb b/lib/rubix/models/template.rb index 5e5ff5b..61992af 100644 --- a/lib/rubix/models/template.rb +++ b/lib/rubix/models/template.rb @@ -75,15 +75,17 @@ def self.build template # Options which control the template import process and the Zabbix # keys they need to be mapped to. IMPORT_OPTIONS = { - :update_hosts => 'rules[host][exist]', - :add_hosts => 'rules[host][missed]', - :update_items => 'rules[item][exist]', - :add_items => 'rules[item][missed]', - :update_triggers => 'rules[trigger][exist]', - :add_triggers => 'rules[trigger][missed]', - :update_graphs => 'rules[graph][exist]', - :add_graphs => 'rules[graph][missed]', - :update_templates => 'rules[template][exist]' + :add_groups => 'rules[groups][createMissing]', + :update_hosts => 'rules[host][updateExisting]', + :add_hosts => 'rules[host][createMissing]', + :update_templates => 'rules[templates][updateExisting]', + :add_templates => 'rules[templates][createMissing]', + :update_items => 'rules[items][updateExisting]', + :add_items => 'rules[items][createMissing]', + :update_triggers => 'rules[triggers][updateExisting]', + :add_triggers => 'rules[triggers][createMissing]', + :update_graphs => 'rules[graphs][updateExisting]', + :add_graphs => 'rules[graphs][createMissing]', }.freeze # Import/update a template from XML contained in an open file @@ -98,14 +100,14 @@ def self.build template # or :add_graphs, all of which default to true. (Linked # templates are controlled with :update_templates.) def self.import fh, options={} - response = web_request("POST", "/templates.php", import_options(options).merge(:import_file => fh)) + response = web_request("POST", "/conf.import.php", import_options(options).merge(:import_file => fh)) File.open('/tmp/output.html', 'w') { |f| f.puts(response.body) } end def self.import_options options {}.tap do |o| self::IMPORT_OPTIONS.each_pair do |name, zabbix_name| - o[zabbix_name] = 'yes' unless options[name] == false + o[zabbix_name] = '1' unless options[name] == false end end end diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb index d3765dc..6108d86 100644 --- a/spec/support/database_helper.rb +++ b/spec/support/database_helper.rb @@ -26,11 +26,12 @@ def initialize config def truncate_all_tables return unless result begin - %w[actions graphs triggers items applications hosts usrgrp media_type scripts].each do |table| + %w[actions graphs triggers items applications hosts media_type scripts].each do |table| @conn.query("DELETE FROM #{table}") end @conn.query('DELETE FROM groups WHERE internal != 1') @conn.query(%Q[DELETE FROM users WHERE alias != 'Admin' AND 'alias' != 'guest']) + @conn.query('DELETE FROM usrgrp WHERE usrgrpid = 42') true rescue => e puts "Could not truncate tables: #{e.class} -- #{e.message}" From 1b5ad8ef8f4ee55bbf97cabcf8602c7bcddbcf00 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 28 Jan 2013 15:53:00 +0400 Subject: [PATCH 16/32] Fix host.update, now it works, but do not update interfaces --- lib/rubix/associations/has_many_interfaces.rb | 2 -- lib/rubix/models/host.rb | 15 ++++++--------- lib/rubix/models/interface.rb | 8 ++++++-- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/rubix/associations/has_many_interfaces.rb b/lib/rubix/associations/has_many_interfaces.rb index b7762a5..7b2098e 100644 --- a/lib/rubix/associations/has_many_interfaces.rb +++ b/lib/rubix/associations/has_many_interfaces.rb @@ -34,5 +34,3 @@ def interface_params end end end - - diff --git a/lib/rubix/models/host.rb b/lib/rubix/models/host.rb index 0452a82..75d5c6b 100644 --- a/lib/rubix/models/host.rb +++ b/lib/rubix/models/host.rb @@ -145,15 +145,12 @@ def create_params end end - # def update_params - # create_params.tap do |cp| - # cp.delete(:groups) - # cp.delete(:templates) - # cp.delete(:macros) - # cp.delete(:interfaces) - # cp[id_field] = id - # end - # end + def update_params + create_params.tap do |cp| + cp.delete(:interfaces) + cp[id_field] = id + end + end # def before_update # response = request('host.massUpdate', { :interfaces => interface_params, :groups => host_group_params, :templates => template_params, :macros => user_macro_params, :hosts => [{id_field => id}]}) diff --git a/lib/rubix/models/interface.rb b/lib/rubix/models/interface.rb index f0b2183..b1d073c 100644 --- a/lib/rubix/models/interface.rb +++ b/lib/rubix/models/interface.rb @@ -34,14 +34,14 @@ def initialize properties={} include Associations::BelongsToHost # - # == Validation == + # == Validation == # def validate raise ValidationError.new("An interface must have a host") unless host_id || host raise ValidationError.new("Either an IP address or a DNS name must be set") if (ip.nil? || ip.empty?) && (dns.nil? || dns.empty?) end - + # # == Requests == # @@ -57,6 +57,10 @@ def create_params } end + def update_params + create_params.merge(id_field => id) + end + def self.build interface new({ :id => interface[id_field].to_i, From a677d7655bc749ec8365a95b8f22226c80f1ff7d Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 28 Jan 2013 16:32:13 +0400 Subject: [PATCH 17/32] template's ids should be unique --- lib/rubix/associations/has_many_templates.rb | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/rubix/associations/has_many_templates.rb b/lib/rubix/associations/has_many_templates.rb index 6debc79..3fcbda3 100644 --- a/lib/rubix/associations/has_many_templates.rb +++ b/lib/rubix/associations/has_many_templates.rb @@ -1,13 +1,13 @@ module Rubix module Associations module HasManyTemplates - + def templates= hs return unless hs @templates = hs @template_ids = hs.map(&:id) end - + def templates return @templates if @templates return unless @template_ids @@ -18,7 +18,7 @@ def template_ids= tids return unless tids @template_ids = tids end - + def template_ids return @template_ids if @template_ids return unless @templates @@ -27,11 +27,8 @@ def template_ids def template_params return [] unless template_ids - template_ids.map { |tid| { 'templateid' => tid } } + template_ids.uniq.map { |tid| { 'templateid' => tid } } end - end end end - - From 503fd4b158e71d67219e40dbc607fb030694bf2e Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Fri, 1 Feb 2013 13:23:54 +0400 Subject: [PATCH 18/32] Add graph creation and spec for it --- .gitignore | 1 + VERSION | 2 +- lib/rubix/models.rb | 1 + lib/rubix/models/graph.rb | 63 ++++++++++++++++++++++++++++ lib/rubix/models/trigger.rb | 9 ++-- spec/requests/action_request_spec.rb | 2 - spec/requests/graph_request_spec.rb | 46 ++++++++++++++++++++ 7 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 lib/rubix/models/graph.rb create mode 100644 spec/requests/graph_request_spec.rb diff --git a/.gitignore b/.gitignore index de3b120..d21f64e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ TAGS* a.out nohop.out spec/test.yml +tmp/ diff --git a/VERSION b/VERSION index 83ac1cc..3afb327 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.14 +0.5.16 diff --git a/lib/rubix/models.rb b/lib/rubix/models.rb index 1db6ab5..282a783 100644 --- a/lib/rubix/models.rb +++ b/lib/rubix/models.rb @@ -18,4 +18,5 @@ module Rubix autoload :Medium, 'rubix/models/medium' autoload :Interface, 'rubix/models/interface' autoload :Inventory, 'rubix/models/inventory' + autoload :Graph, 'rubix/models/graph' end diff --git a/lib/rubix/models/graph.rb b/lib/rubix/models/graph.rb new file mode 100644 index 0000000..15f4bac --- /dev/null +++ b/lib/rubix/models/graph.rb @@ -0,0 +1,63 @@ +module Rubix + class Graph < Model + # + # == Properties & Finding == + # + + def initialize properties={} + super(properties) + end + + zabbix_attr :name, :required => true + zabbix_attr :width, :required => true + zabbix_attr :height, :required => true + zabbix_attr :graph_items + + # + # == Validation = + # + + def validate + raise ValidationError.new("A graph must have at least one graph item.") if graph_items.nil? || graph_items.empty? + graph_items.each do |gi| + raise ValidationError.new("A graph item must have item_id property.") unless gi[:item_id] + raise ValidationError.new("A graph item must have color property.") unless gi[:color] + end + true + end + + # + # == Requests == + # + + def create_params + { + :name => name, :height => height, :width => width + }.tap do |cp| + cp[:gitems] = graph_items.map { |gi| {:itemid => gi[:item_id], :color => gi[:color]}} + end + end + + def update_params + { id_field => id, :name => name, :hosts => {:hostid => host_id}} + end + + def self.find_params options={} + super().merge({ + :filter => { + :name => options[:name], + id_field => options[:id] + } + }) + end + + def self.build app + params = { + :id => app[id_field].to_i, + :name => app['name'] + } + new(params) + end + end +end + diff --git a/lib/rubix/models/trigger.rb b/lib/rubix/models/trigger.rb index bb564a3..f6f5ce7 100644 --- a/lib/rubix/models/trigger.rb +++ b/lib/rubix/models/trigger.rb @@ -87,7 +87,7 @@ def create_params def self.get_params super().merge(:selectItems => :refer) end - + def self.find_params options={} fp = { :filter => { @@ -99,6 +99,8 @@ def self.find_params options={} fp[:templateids] = [options[:template_id]] when options[:host_id] fp[:hostids] = [options[:host_id]] + when options[:id] + fp[:triggerids] = [options[:id]] end end super().merge(fp) @@ -113,8 +115,9 @@ def self.build trigger :url => trigger['url'], :status => STATUS_NAMES[trigger['status'].to_i], :priority => PRIORITY_NAMES[trigger['priority'].to_i], - :item_ids => (trigger['items'] || []).map { |item| item['itemid'].to_i } - }.merge(host_or_template_params_from_id(trigger['hosts'].first['hostid'].to_i))) + :item_ids => (trigger['items'] || []).map { |item| item['itemid'].to_i }, + :template_id => trigger['templateid'].to_i + }) end def self.host_or_template_params_from_id id diff --git a/spec/requests/action_request_spec.rb b/spec/requests/action_request_spec.rb index 0567721..3909ea7 100644 --- a/spec/requests/action_request_spec.rb +++ b/spec/requests/action_request_spec.rb @@ -4,8 +4,6 @@ before do integration_test - Rubix.logger = Logger.new STDOUT - Rubix.logger.level = Logger::DEBUG @user_group = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) @user = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix', :last_name => 'user', :password => 'pass', :user_groups => [@user_group])) end diff --git a/spec/requests/graph_request_spec.rb b/spec/requests/graph_request_spec.rb new file mode 100644 index 0000000..2597c70 --- /dev/null +++ b/spec/requests/graph_request_spec.rb @@ -0,0 +1,46 @@ +require 'spec_helper' + +describe "Graphs" do + + before do + integration_test + @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host = Rubix::Host.find(:id => @host.id) + @item = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix item description 1', :host_id => @host.id, :interface_id => @host.interfaces.first.id, :value_type => :character, :units => 'B')) + end + + after do + truncate_all_tables + end + + describe "when not existing" do + it "returns nil on find" do + Rubix::Graph.find(:name => 'graph_1').should be_nil + end + + it "can be created" do + graph = Rubix::Graph.new(:name => 'graph1', :height => 480, :width => 640, :graph_items => [:item_id => @item.id, :color => '000000']) + graph.save.should be_true + graph.id.should_not be_nil + graph.id.should_not == 0 + end + end + + describe "when existing" do + + before do + @graph = ensure_save(Rubix::Graph.new(:name => 'graph_1', :height => 480, :width => 640, :graph_items => [:item_id => @item.id, :color => '000000'])) + end + + it "can be founded" do + Rubix::Graph.find(:name => 'graph_1').should_not be_nil + end + + it "can be destroyed" do + @graph.destroy + Rubix::Graph.find(:name => 'graph_1').should be_nil + end + end +end + From 7d39e005157122b8a2aaa191a96360a43234962a Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Fri, 1 Feb 2013 17:47:28 +0400 Subject: [PATCH 19/32] Screen and ScreenItem added --- lib/rubix/models.rb | 2 + lib/rubix/models/screen.rb | 56 ++++++++++++ lib/rubix/models/screen_item.rb | 106 ++++++++++++++++++++++ spec/requests/screen_item_request_spec.rb | 50 ++++++++++ spec/requests/screen_request_spec.rb | 43 +++++++++ spec/support/database_helper.rb | 2 +- 6 files changed, 258 insertions(+), 1 deletion(-) create mode 100644 lib/rubix/models/screen.rb create mode 100644 lib/rubix/models/screen_item.rb create mode 100644 spec/requests/screen_item_request_spec.rb create mode 100644 spec/requests/screen_request_spec.rb diff --git a/lib/rubix/models.rb b/lib/rubix/models.rb index 282a783..2a5d066 100644 --- a/lib/rubix/models.rb +++ b/lib/rubix/models.rb @@ -19,4 +19,6 @@ module Rubix autoload :Interface, 'rubix/models/interface' autoload :Inventory, 'rubix/models/inventory' autoload :Graph, 'rubix/models/graph' + autoload :Screen, 'rubix/models/screen' + autoload :ScreenItem, 'rubix/models/screen_item' end diff --git a/lib/rubix/models/screen.rb b/lib/rubix/models/screen.rb new file mode 100644 index 0000000..68ab8b1 --- /dev/null +++ b/lib/rubix/models/screen.rb @@ -0,0 +1,56 @@ +module Rubix + class Screen < Model + # + # == Properties & Finding == + # + + def initialize properties={} + super(properties) + end + + zabbix_attr :name, :required => true + zabbix_attr :wsize, :default => 1 + zabbix_attr :hsize, :default => 1 + zabbix_attr :screen_items + + # + # == Validation = + # + + def validate + true + end + + # + # == Requests == + # + + def create_params + { + :name => name, :hsize => hsize, :wsize => wsize + } + end + + def update_params + super + end + + def self.find_params options={} + super().merge({ + :filter => { + :name => options[:name], + id_field => options[:id] + } + }) + end + + def self.build app + params = { + :id => app[id_field].to_i, + :name => app['name'] + } + new(params) + end + end +end + diff --git a/lib/rubix/models/screen_item.rb b/lib/rubix/models/screen_item.rb new file mode 100644 index 0000000..f0ff1a5 --- /dev/null +++ b/lib/rubix/models/screen_item.rb @@ -0,0 +1,106 @@ +module Rubix + class ScreenItem < Model + + zabbix_define :RESOURCE_TYPE, { + :graph => 0, + :simple_graph => 1, + :map => 2, + :plain_text => 3, + :host_info => 4, + :trigger_info => 5, + :server_info => 6, + :clock => 7, + :screen => 8, + :trigger_overview => 9, + :data_overview => 10, + :url => 11, + :action_history => 12, + :event_history => 13, + :hostgroup_trigger_status => 14, + :system_status => 15, + :host_trigger_status => 16 + } + + zabbix_define :H_ALIGN, { + :center => 0, + :left => 1, + :right => 2 + } + + zabbix_define :V_ALIGN, { + :middle => 0, + :top => 1, + :bottom => 2 + } + + # + # == Properties & Finding == + # + + def initialize properties={} + super(properties) + end + + zabbix_attr :colspan, :required => true, :default => 1 + zabbix_attr :rowspan, :required => true, :default => 1 + zabbix_attr :resource_id, :required => true + zabbix_attr :resource_type, :required => true + zabbix_attr :screen_id, :required => true + zabbix_attr :dynamic, :default => 0 + zabbix_attr :elements, :default => 25 + zabbix_attr :halign, :default => :center + zabbix_attr :valign, :default => :middle + zabbix_attr :height, :default => 200 + zabbix_attr :width, :default => 320 + zabbix_attr :x, :default => 0 + zabbix_attr :y, :default => 0 + zabbix_attr :sort_triggers + zabbix_attr :style + zabbix_attr :url + + # + # == Validation = + # + + def validate + super + true + end + + # + # == Requests == + # + + def create_params + { + :colspan => colspan, + :rowspan => rowspan, + :resourceid => resource_id, + :resourcetype => RESOURCE_TYPE_CODES[resource_type], + :screenid => screen_id + } + end + + def update_params + super + end + + def self.find_params options={} + super().merge({ + :filter => { + :name => options[:name], + id_field => options[:id] + } + }) + end + + def self.build app + params = { + :id => app[id_field].to_i, + :name => app['name'] + } + new(params) + end + end +end + diff --git a/spec/requests/screen_item_request_spec.rb b/spec/requests/screen_item_request_spec.rb new file mode 100644 index 0000000..ea738ce --- /dev/null +++ b/spec/requests/screen_item_request_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe "ScreenItems" do + + before do + Rubix.logger = Logger.new STDOUT + Rubix.logger.level = Logger::DEBUG + integration_test + + @screen = ensure_save(Rubix::Screen.new(:name => 'screen_1')) + @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host = Rubix::Host.find(:id => @host.id) + @item = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix item description 1', :host_id => @host.id, :interface_id => @host.interfaces.first.id, :value_type => :character, :units => 'B')) + @graph = ensure_save(Rubix::Graph.new(:name => 'graph1', :height => 480, :width => 640, :graph_items => [:item_id => @item.id, :color => '000000'])) + end + + after do + truncate_all_tables + end + + describe "when not existing" do + it "returns nil on find" do + Rubix::ScreenItem.find(:name => 'screen_item_1').should be_nil + end + + it "can be created" do + screen_item = Rubix::ScreenItem.new(:resource_id => @graph.id, :resource_type => :graph, :screen_id => @screen.id) + screen_item.save.should be_true + screen_item.id.should_not be_nil + screen_item.id.should_not == 0 + end + end + + describe "when existing" do + + before do + @screen_item = ensure_save Rubix::ScreenItem.new(:resource_id => @graph.id, :resource_type => :graph, :screen_id => @screen.id) + end + + it "can be founded" do + Rubix::ScreenItem.find(:name => 'screen_item_2').should_not be_nil + end + + it "can be destroyed" do + @screen_item.destroy + Rubix::ScreenItem.find(:name => 'screen_item_2').should be_nil + end + end +end diff --git a/spec/requests/screen_request_spec.rb b/spec/requests/screen_request_spec.rb new file mode 100644 index 0000000..6cb3960 --- /dev/null +++ b/spec/requests/screen_request_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe "Screens" do + + before do + Rubix.logger = Logger.new STDOUT + Rubix.logger.level = Logger::DEBUG + integration_test + end + + after do + truncate_all_tables + end + + describe "when not existing" do + it "returns nil on find" do + Rubix::Screen.find(:name => 'screen_1').should be_nil + end + + it "can be created" do + screen = Rubix::Screen.new(:name => 'screen_1') + screen.save.should be_true + screen.id.should_not be_nil + screen.id.should_not == 0 + end + end + + describe "when existing" do + + before do + @screen = ensure_save(Rubix::Screen.new(:name => 'screen_2')) + end + + it "can be founded" do + Rubix::Screen.find(:name => 'screen_2').should_not be_nil + end + + it "can be destroyed" do + @screen.destroy + Rubix::Screen.find(:name => 'screen_2').should be_nil + end + end +end diff --git a/spec/support/database_helper.rb b/spec/support/database_helper.rb index 6108d86..8125ca3 100644 --- a/spec/support/database_helper.rb +++ b/spec/support/database_helper.rb @@ -26,7 +26,7 @@ def initialize config def truncate_all_tables return unless result begin - %w[actions graphs triggers items applications hosts media_type scripts].each do |table| + %w[screens actions graphs triggers items applications hosts media_type scripts].each do |table| @conn.query("DELETE FROM #{table}") end @conn.query('DELETE FROM groups WHERE internal != 1') From faefefb8bcae6d9c83592af4e790dd1f461f45ed Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 4 Feb 2013 14:53:24 +0400 Subject: [PATCH 20/32] Screen with nested ScreenItems now can be saved --- lib/rubix/associations.rb | 1 + .../associations/has_many_screen_items.rb | 30 +++++++++++++++++++ lib/rubix/models/screen.rb | 12 ++++++-- spec/requests/screen_item_request_spec.rb | 2 -- spec/requests/screen_request_spec.rb | 20 +++++++++++-- 5 files changed, 58 insertions(+), 7 deletions(-) create mode 100644 lib/rubix/associations/has_many_screen_items.rb diff --git a/lib/rubix/associations.rb b/lib/rubix/associations.rb index 09d8202..8eafa6e 100644 --- a/lib/rubix/associations.rb +++ b/lib/rubix/associations.rb @@ -11,6 +11,7 @@ module Associations autoload :HasManyUserGroups, 'rubix/associations/has_many_user_groups' autoload :HasManyConditions, 'rubix/associations/has_many_conditions' autoload :HasManyInterfaces, 'rubix/associations/has_many_interfaces' + autoload :HasManyScreenItems, 'rubix/associations/has_many_screen_items' autoload :HasInventory, 'rubix/associations/has_inventory' autoload :BelongsToHost, 'rubix/associations/belongs_to_host' diff --git a/lib/rubix/associations/has_many_screen_items.rb b/lib/rubix/associations/has_many_screen_items.rb new file mode 100644 index 0000000..cd7c7ad --- /dev/null +++ b/lib/rubix/associations/has_many_screen_items.rb @@ -0,0 +1,30 @@ +module Rubix + module Associations + module HasManyScreenItems + + def screen_items= hs + return unless hs + @screen_items = hs + @screen_item_ids = hs.map(&:id) + end + + def screen_items + return @screen_items if @screen_items + return [] unless @screen_item_ids + @screen_items = @screen_item_ids.map { |hid| screen_item.find(:id => hid) } + end + + def screen_item_ids= hids + return unless hids + @screen_item_ids = hids + end + + def screen_item_ids + return @screen_item_ids if @screen_item_ids + return unless @screen_items + @screen_item_ids = @screen_items.map(&:id) + end + end + end +end + diff --git a/lib/rubix/models/screen.rb b/lib/rubix/models/screen.rb index 68ab8b1..50c3e6f 100644 --- a/lib/rubix/models/screen.rb +++ b/lib/rubix/models/screen.rb @@ -1,17 +1,20 @@ module Rubix class Screen < Model + include Associations::HasManyScreenItems # # == Properties & Finding == # def initialize properties={} super(properties) + + self.screen_item_ids = properties[:screen_item_ids] + self.screen_items = properties[:screen_items].map { |si| ScreenItem.new(si) } if properties[:screen_items] end zabbix_attr :name, :required => true zabbix_attr :wsize, :default => 1 zabbix_attr :hsize, :default => 1 - zabbix_attr :screen_items # # == Validation = @@ -27,7 +30,8 @@ def validate def create_params { - :name => name, :hsize => hsize, :wsize => wsize + :name => name, :hsize => hsize, :wsize => wsize, + :screenitems => self.screen_items.map { |si| si.create_params } } end @@ -37,6 +41,7 @@ def update_params def self.find_params options={} super().merge({ + :selectScreenItems => 'refer', :filter => { :name => options[:name], id_field => options[:id] @@ -47,7 +52,8 @@ def self.find_params options={} def self.build app params = { :id => app[id_field].to_i, - :name => app['name'] + :name => app['name'], + :screen_items => app['screenitems'] } new(params) end diff --git a/spec/requests/screen_item_request_spec.rb b/spec/requests/screen_item_request_spec.rb index ea738ce..ba85a8b 100644 --- a/spec/requests/screen_item_request_spec.rb +++ b/spec/requests/screen_item_request_spec.rb @@ -3,8 +3,6 @@ describe "ScreenItems" do before do - Rubix.logger = Logger.new STDOUT - Rubix.logger.level = Logger::DEBUG integration_test @screen = ensure_save(Rubix::Screen.new(:name => 'screen_1')) diff --git a/spec/requests/screen_request_spec.rb b/spec/requests/screen_request_spec.rb index 6cb3960..414b572 100644 --- a/spec/requests/screen_request_spec.rb +++ b/spec/requests/screen_request_spec.rb @@ -3,8 +3,6 @@ describe "Screens" do before do - Rubix.logger = Logger.new STDOUT - Rubix.logger.level = Logger::DEBUG integration_test end @@ -23,6 +21,24 @@ screen.id.should_not be_nil screen.id.should_not == 0 end + + end + + describe "with screen items" do + before do + @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) + @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) + @host = Rubix::Host.find(:id => @host.id) + @item = ensure_save(Rubix::Item.new(:key => 'rubix.spec1', :name => 'rubix item description 1', :host_id => @host.id, :interface_id => @host.interfaces.first.id, :value_type => :character, :units => 'B')) + @graph = ensure_save(Rubix::Graph.new(:name => 'graph1', :height => 480, :width => 640, :graph_items => [:item_id => @item.id, :color => '000000'])) + end + + it "can be created" do + screen = Rubix::Screen.new(:name => 'screen_1', :screen_items => [:resource_id => @graph.id, :resource_type => :graph]) + screen.save.should be_true + screen = Rubix::Screen.find(:id => screen.id) + screen.screen_items.size.should == 1 + end end describe "when existing" do From d7938e06684aa7415f61234c88fe529c8e5a57ab Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 4 Feb 2013 18:00:30 +0400 Subject: [PATCH 21/32] Change screen_items and screen --- .../associations/has_many_screen_items.rb | 21 ++---------- lib/rubix/models/screen.rb | 9 ++--- lib/rubix/models/screen_item.rb | 34 ++++++++++++++++--- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/lib/rubix/associations/has_many_screen_items.rb b/lib/rubix/associations/has_many_screen_items.rb index cd7c7ad..087464c 100644 --- a/lib/rubix/associations/has_many_screen_items.rb +++ b/lib/rubix/associations/has_many_screen_items.rb @@ -2,27 +2,12 @@ module Rubix module Associations module HasManyScreenItems - def screen_items= hs - return unless hs - @screen_items = hs - @screen_item_ids = hs.map(&:id) + def screen_items= sis + @screen_items = sis end def screen_items - return @screen_items if @screen_items - return [] unless @screen_item_ids - @screen_items = @screen_item_ids.map { |hid| screen_item.find(:id => hid) } - end - - def screen_item_ids= hids - return unless hids - @screen_item_ids = hids - end - - def screen_item_ids - return @screen_item_ids if @screen_item_ids - return unless @screen_items - @screen_item_ids = @screen_items.map(&:id) + @screen_items || [] end end end diff --git a/lib/rubix/models/screen.rb b/lib/rubix/models/screen.rb index 50c3e6f..74ef97f 100644 --- a/lib/rubix/models/screen.rb +++ b/lib/rubix/models/screen.rb @@ -8,8 +8,7 @@ class Screen < Model def initialize properties={} super(properties) - self.screen_item_ids = properties[:screen_item_ids] - self.screen_items = properties[:screen_items].map { |si| ScreenItem.new(si) } if properties[:screen_items] + self.screen_items = properties[:screen_items].map { |si| si.is_a?(ScreenItem) ? si : ScreenItem.new(si) } if properties[:screen_items] end zabbix_attr :name, :required => true @@ -35,10 +34,6 @@ def create_params } end - def update_params - super - end - def self.find_params options={} super().merge({ :selectScreenItems => 'refer', @@ -53,7 +48,7 @@ def self.build app params = { :id => app[id_field].to_i, :name => app['name'], - :screen_items => app['screenitems'] + :screen_items => app['screenitems'].map { |si| ScreenItem.build si } } new(params) end diff --git a/lib/rubix/models/screen_item.rb b/lib/rubix/models/screen_item.rb index f0ff1a5..60f6909 100644 --- a/lib/rubix/models/screen_item.rb +++ b/lib/rubix/models/screen_item.rb @@ -77,7 +77,18 @@ def create_params :rowspan => rowspan, :resourceid => resource_id, :resourcetype => RESOURCE_TYPE_CODES[resource_type], - :screenid => screen_id + :screenid => screen_id, + :dynamic => dynamic, + :elements => elements, + :halign => H_ALIGN_CODES[halign], + :valign => V_ALIGN_CODES[valign], + :height => height, + :width => width, + :x => x, + :y => y, + :sort_triggers => sort_triggers, + :style => style, + :url => url } end @@ -94,10 +105,25 @@ def self.find_params options={} }) end - def self.build app + def self.build params params = { - :id => app[id_field].to_i, - :name => app['name'] + :id => params[id_field].to_i, + :colspan => params["colspan"], + :rowspan => params["rowspan"], + :resource_id => params["resourceid"], + :resource_type => RESOURCE_TYPE_NAMES[params["resourcetype"].to_i], + :screen_id => params["screenid"], + :dynamic => params["dynamic"], + :elements => params["elements"], + :halign => H_ALIGN_NAMES[params["halign"].to_i], + :valign => V_ALIGN_NAMES[params["valign"].to_i], + :height => params["height"], + :width => params["width"], + :x => params["x"], + :y => params["y"], + :sort_triggers => params["sort_triggers"], + :style => params["style"], + :url => params["url"] } new(params) end From 9fed88d093cbc3935db523774a3fcbf8b852ee0d Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Fri, 8 Feb 2013 15:53:58 +0400 Subject: [PATCH 22/32] Action creation added --- lib/rubix/associations.rb | 5 +- lib/rubix/associations/has_many_conditions.rb | 3 - lib/rubix/associations/has_message.rb | 15 ++++ lib/rubix/models.rb | 1 + lib/rubix/models/action.rb | 6 +- lib/rubix/models/message.rb | 45 +++++++++++ lib/rubix/models/operation.rb | 81 +++++-------------- spec/requests/action_request_spec.rb | 16 +++- 8 files changed, 101 insertions(+), 71 deletions(-) create mode 100644 lib/rubix/associations/has_message.rb create mode 100644 lib/rubix/models/message.rb diff --git a/lib/rubix/associations.rb b/lib/rubix/associations.rb index 8eafa6e..88b27f8 100644 --- a/lib/rubix/associations.rb +++ b/lib/rubix/associations.rb @@ -1,6 +1,6 @@ module Rubix module Associations - + autoload :HasManyHosts, 'rubix/associations/has_many_hosts' autoload :HasManyTemplates, 'rubix/associations/has_many_templates' autoload :HasManyHostGroups, 'rubix/associations/has_many_host_groups' @@ -13,7 +13,8 @@ module Associations autoload :HasManyInterfaces, 'rubix/associations/has_many_interfaces' autoload :HasManyScreenItems, 'rubix/associations/has_many_screen_items' autoload :HasInventory, 'rubix/associations/has_inventory' - + autoload :HasMessage, 'rubix/associations/has_message' + autoload :BelongsToHost, 'rubix/associations/belongs_to_host' autoload :BelongsToTemplate, 'rubix/associations/belongs_to_template' autoload :BelongsToItem, 'rubix/associations/belongs_to_item' diff --git a/lib/rubix/associations/has_many_conditions.rb b/lib/rubix/associations/has_many_conditions.rb index d8b80b0..b2b4060 100644 --- a/lib/rubix/associations/has_many_conditions.rb +++ b/lib/rubix/associations/has_many_conditions.rb @@ -15,9 +15,6 @@ def conditions= cs c.kind_of?(Condition) ? c : Condition.new(c) end end - end end end - - diff --git a/lib/rubix/associations/has_message.rb b/lib/rubix/associations/has_message.rb new file mode 100644 index 0000000..549095e --- /dev/null +++ b/lib/rubix/associations/has_message.rb @@ -0,0 +1,15 @@ +module Rubix + module Associations + module HasMessage + + def message + @message + end + + def message= m + @message = m.kind_of?(Message) ? m : Message.new(m) + end + end + end +end + diff --git a/lib/rubix/models.rb b/lib/rubix/models.rb index 2a5d066..4c47322 100644 --- a/lib/rubix/models.rb +++ b/lib/rubix/models.rb @@ -21,4 +21,5 @@ module Rubix autoload :Graph, 'rubix/models/graph' autoload :Screen, 'rubix/models/screen' autoload :ScreenItem, 'rubix/models/screen_item' + autoload :Message, 'rubix/models/message' end diff --git a/lib/rubix/models/action.rb b/lib/rubix/models/action.rb index 959890c..e6e8013 100644 --- a/lib/rubix/models/action.rb +++ b/lib/rubix/models/action.rb @@ -91,7 +91,7 @@ def self.find_params options={} end def self.get_params - super().merge({:select_conditions => :refer, :select_operations => :refer}) + super().merge({:selectConditions => :refer, :selectOperations => :refer}) end def self.build action @@ -107,8 +107,8 @@ def self.build action :send_recovery_message => (action['recovery_msg'].to_i == 1), :recovery_message_subject => action['r_shortdata'], :recovery_message_body => action['r_longdata'], - :conditions => (action['conditions'] || []).map { |c| Condition.build(c) }, - :operations => (action['operations'] || []).map { |o| Operation.build(o) } + :conditions => (action['conditions'] || []).map { |id, c| Condition.build(c) }, + :operations => (action['operations'] || []).map { |id, o| Operation.build(o) } }) end diff --git a/lib/rubix/models/message.rb b/lib/rubix/models/message.rb new file mode 100644 index 0000000..0c17c40 --- /dev/null +++ b/lib/rubix/models/message.rb @@ -0,0 +1,45 @@ +module Rubix + class Message < Model + + # + # == Properties & Finding == + # + + zabbix_attr :use_default_message, :default => true + zabbix_attr :subject + zabbix_attr :message + + def initialize properties={} + super(properties) + self.media_type_id = properties[:media_type_id] + end + + # + # == Associations == + # + + include Associations::BelongsToMediaType + + # + # == Requests == + # + + def create_params + { + :default_msg => use_default_message ? '1' : '0', + :subject => subject, + :message => message, + :mediatypeid => media_type_id + } + end + + def self.build msg + new({ + :use_default_message => msg['default_msg'] == '1', + :subject => msg['subject'], + :message => msg['message'], + :media_type_id => msg['mediatypeid'] + }) + end + end +end diff --git a/lib/rubix/models/operation.rb b/lib/rubix/models/operation.rb index a706bc5..08b368b 100644 --- a/lib/rubix/models/operation.rb +++ b/lib/rubix/models/operation.rb @@ -16,21 +16,11 @@ class Operation < Model :host_disable => 9 } - # Numeric codes for the type of object that should be notified. - # Default will be 'group'. - zabbix_define :NOTIFICATION_OBJECT, { - :user => 0, - :user_group => 1 - } - # # == Properties & Finding == # zabbix_attr :type, :default => :message, :required => true - zabbix_attr :message_subject, :default => Action::MESSAGE_SUBJECT - zabbix_attr :message_body, :default => Action::MESSAGE_BODY - zabbix_attr :use_default_message, :default => true zabbix_attr :escalation_time, :default => 0 zabbix_attr :start, :default => 1 zabbix_attr :stop, :default => 1 @@ -42,35 +32,16 @@ def step= s def initialize properties={} super(properties) - self.step = properties[:step] if properties[:step] - - self.user_id = properties[:user_id] - self.user = properties[:user] + self.step = properties[:step] if properties[:step] - self.user_group_id = properties[:user_group_id] - self.user_group = properties[:user_group] + self.user_ids = properties[:user_ids] + self.users = properties[:users] - self.conditions = (properties[:conditions] || []) + self.user_group_ids = properties[:user_group_ids] + self.user_groups = properties[:user_groups] - self.media_type = properties[:media_type] - self.media_type_id = properties[:media_type_id] - end - - def notification_object_name - case - when user_id then :user - when user_group_id then :user_group - else - raise Error.new("An #{resource_name} must have either a user or a user group.") - end - end - - def notification_object_id - if user_id || user_group_id - return user_id || user_group_id - else - raise Error.new("An #{resource_name} must have either a user or a user group.") - end + self.conditions = (properties[:conditions] || []) + self.message = properties[:message] || Message.new end # @@ -78,9 +49,9 @@ def notification_object_id # include Associations::HasManyConditions - include Associations::BelongsToUser - include Associations::BelongsToUserGroup - include Associations::BelongsToMediaType + include Associations::HasManyUsers + include Associations::HasManyUserGroups + include Associations::HasMessage # # == Requests == @@ -89,18 +60,17 @@ def notification_object_id def create_params { :operationtype => self.class::TYPE_CODES[type], - :object => self.class::NOTIFICATION_OBJECT_CODES[notification_object_name], - :objectid => notification_object_id, - :shortdata => message_subject, - :longdata => message_body, - :default_msg => (use_default_message ? 1 : 0), :evaltype => Condition::JOIN_CODES[condition_operator], :esc_period => escalation_time, :esc_step_from => start, :esc_step_to => stop }.tap do |cp| - cp[:opconditions] = conditions.map(&:to_hash) unless conditions.empty? - cp[:opmediatypes] = [{ :mediatypeid => media_type_id }] if media_type_id + cp[:opconditions] = conditions.map(&:to_hash) unless conditions.empty? + if user_ids + cp[:opmessage_usr] = user_ids.map { |id| { :userid => id } } unless user_ids.empty? + end + cp[:opmessage_grp] = user_group_ids.map { |id| { :usrgrpid => id } } unless user_group_ids.empty? + cp[:opmessage] = message.to_hash end end @@ -108,25 +78,18 @@ def self.build operation new({ :id => operation[id_field].to_i, :type => self::TYPE_NAMES[operation['operationtype'].to_i], - :message_subject => operation['shortdata'], - :message_body => operation['longdata'], :escalation_period => operation['esc_period'].to_i, - :use_default_message => (operation['default_msg'].to_i == 1), :condition_operator => Condition::JOIN_NAMES[operation['evaltype'].to_i], :conditions => (operation['opconditions'] || []).map { |c| Condition.build(c) }, :start => operation['esc_step_from'].to_i, - :stop => operation['esc_step_to'].to_i + :stop => operation['esc_step_to'].to_i, + :user_ids => (operation['opmessage_usr'] || []).map { |e| e['userid'].to_i }, + :user_group_ids => (operation['opmessage_grp'] || []).map { |e| e['usrgrpid'].to_i } }).tap do |o| - if self::NOTIFICATION_OBJECT_NAMES[operation['object'].to_i] == :user - o.user_id = operation['objectid'] - else - o.user_group_id = operation['objectid'] - end - if (operation['opmediatypes'] || []).first - o.media_type_id = (operation['opmediatypes'] || []).first['mediatypeid'].to_i - end + if operation['opmessage'] + o.message = Message.build(operation['opmessage']) + end end end - end end diff --git a/spec/requests/action_request_spec.rb b/spec/requests/action_request_spec.rb index 3909ea7..d6a6e57 100644 --- a/spec/requests/action_request_spec.rb +++ b/spec/requests/action_request_spec.rb @@ -4,7 +4,9 @@ before do integration_test - @user_group = ensure_save(Rubix::UserGroup.new(:name => 'rubix_spec_user_group_1')) + Rubix.logger = Logger.new STDOUT + Rubix.logger.level = Logger::DEBUG + @user_group = Rubix::UserGroup.find_or_create(:name => 'rubix_spec_user_group_1') @user = ensure_save(Rubix::User.new(:username => 'rubix_spec_user_1', :first_name => 'rubix', :last_name => 'user', :password => 'pass', :user_groups => [@user_group])) end @@ -19,7 +21,7 @@ end it "can be created" do - a = Rubix::Action.new(:name => 'rubix_spec_action_1', :operations => [{:user_group => @user_group}]) + a = Rubix::Action.new(:name => 'rubix_spec_action_1', :operations => [{:user_groups => [@user_group]}]) a.save.should be_true na = Rubix::Action.find(:name => 'rubix_spec_action_1') @@ -28,11 +30,18 @@ na.operations.size.should == 1 end + it "can be updated" do + a = ensure_save(Rubix::Action.new(:name => 'rubix_spec_action_1', :operations => [{:user_groups => [@user_group]}])) + + na = Rubix::Action.find(:name => 'rubix_spec_action_1') + na.save.should be_true + end + end describe "when existing" do before do - @action = ensure_save(Rubix::Action.new(:name => 'rubix_spec_action_1', :operations => [{:user_group => @user_group}])) + @action = ensure_save(Rubix::Action.new(:name => 'rubix_spec_action_1', :operations => [{:user_groups => [@user_group]}])) end it "can be destroyed" do @@ -41,5 +50,4 @@ end end - end From 6686b1783a3c37c3777ed8811afc323681c9f6df Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 12 Feb 2013 19:24:23 +0400 Subject: [PATCH 23/32] Fix validation, when value is Symbol --- lib/rubix/models/model.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index 9762a37..67be214 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -143,7 +143,13 @@ def save def validate self.class.properties.each_pair do |property, options| property_value = self.send property - raise ValidationError.new("A #{self.class.resource_name} must have a #{property}") if options[:required] && (property_value.nil? || (!property_value.is_a?(Fixnum) && property_value.empty?)) + if options[:required] + if property_value.nil? + raise ValidationError.new("A #{self.class.resource_name} #{property} can't be nil") + elsif property_value.is_a?(Array) && property_value.empty? + raise ValidationError.new("A #{self.class.resource_name} must have a #{property}") + end + end end true end From cdd1146cd5fec398d602d29b65fc8642084998d0 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 19 Feb 2013 16:52:36 +0400 Subject: [PATCH 24/32] Support 2.0.5 zabbix version --- lib/rubix.rb | 2 +- lib/rubix/connection.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rubix.rb b/lib/rubix.rb index a6cb672..67166f4 100644 --- a/lib/rubix.rb +++ b/lib/rubix.rb @@ -7,7 +7,7 @@ module Rubix - SERVER_VERSION = '2.0.4'.freeze + SERVER_VERSION = ['2.0.4', '2.0.5'].freeze autoload :Connection, 'rubix/connection' autoload :Response, 'rubix/response' diff --git a/lib/rubix/connection.rb b/lib/rubix/connection.rb index f3befe2..6d1ec61 100644 --- a/lib/rubix/connection.rb +++ b/lib/rubix/connection.rb @@ -115,7 +115,7 @@ def authorize! raise AuthenticationError.new("Malformed response from Zabbix API: #{response.body}") unless response.string? @auth = response.result - raise VersionError.new("Incorrect Zabbix Server API version, should be #{SERVER_VERSION}") unless api_version == SERVER_VERSION + raise VersionError.new("Incorrect Zabbix Server API version #{api_version}, should be one of #{SERVER_VERSIONS.join(', ')}") unless SERVER_VERSIONS.include? api_version @auth end From d2ab561e28aac162c6e42b3f86df1d1d832e01ce Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Tue, 19 Feb 2013 16:54:56 +0400 Subject: [PATCH 25/32] Typo --- lib/rubix.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubix.rb b/lib/rubix.rb index 67166f4..7b63c0e 100644 --- a/lib/rubix.rb +++ b/lib/rubix.rb @@ -7,7 +7,7 @@ module Rubix - SERVER_VERSION = ['2.0.4', '2.0.5'].freeze + SERVER_VERSIONS = ['2.0.4', '2.0.5'].freeze autoload :Connection, 'rubix/connection' autoload :Response, 'rubix/response' From bf16d49f48874cdebc59b60f7edc3e7e769fbbb2 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 21 Feb 2013 00:30:14 +0400 Subject: [PATCH 26/32] Add save! method to any model like ActiveRecord one --- lib/rubix/models/model.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index 67be214..5751fc0 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -134,6 +134,10 @@ def save new_record? ? create : update end + def save! + raise Rubix::Error.new(Rubix.connection.last_response.body) unless save + end + # Validate this record. # # Override this method in a subclass and have it raise a From 647cb0504433c730cf762d79bc2bfc84b71d183e Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 25 Feb 2013 20:55:09 +0400 Subject: [PATCH 27/32] UserMacro returned in new format --- lib/rubix/models/host.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/rubix/models/host.rb b/lib/rubix/models/host.rb index 75d5c6b..1264e75 100644 --- a/lib/rubix/models/host.rb +++ b/lib/rubix/models/host.rb @@ -179,7 +179,7 @@ def self.build host :host_group_ids => host['groups'].map { |group| group['groupid'].to_i }, :template_ids => host['parentTemplates'].map { |template| (template['templateid'] || template[id_field]).to_i }, - :user_macros => host['macros'].map { |um| UserMacro.new(:host_id => um[id_field].to_i, :id => um['hostmacroid'], :value => um['value'], :macro => um['macro']) }, + :user_macros => host['macros'].map { |id, um| UserMacro.new(:host_id => um[id_field].to_i, :id => um['hostmacroid'], :value => um['value'], :macro => um['macro']) }, :interfaces => host['interfaces'].values, :status => self::STATUS_NAMES[host['status'].to_i], From d019a05aa9f7e20678b612d1c16dc55b6337a711 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Mon, 25 Feb 2013 22:15:15 +0400 Subject: [PATCH 28/32] Bump version --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3afb327..d8aef81 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.16 +0.5.17 From 861468527accca94461db1d10bbded09c0fce603 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 28 Feb 2013 20:57:52 +0400 Subject: [PATCH 29/32] Add delta and formula(params) to items --- VERSION | 2 +- lib/rubix/models/item.rb | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/VERSION b/VERSION index d8aef81..b7a8bdf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.17 +0.5.18 diff --git a/lib/rubix/models/item.rb b/lib/rubix/models/item.rb index 4008312..01bb0b2 100644 --- a/lib/rubix/models/item.rb +++ b/lib/rubix/models/item.rb @@ -59,6 +59,15 @@ class Item < Model :not_supported => 3 } + # The numeric codes for the delta types of a Zabbix item. + # + # The default will be :as_is + zabbix_define :DELTA, { + :as_is => 0, + :speed_per_second => 1, + :delta => 2 + } + # Return the +value_type+ name (:float, :text, &c.) for a Zabbix # item's value type by examining the given +value+. def self.value_type_from_value value @@ -88,6 +97,8 @@ def self.value_code_from_value value zabbix_attr :status zabbix_attr :frequency, :required => true, :default => 60 zabbix_attr :name, :required => true + zabbix_attr :delta, :defalut => :as_is + zabbix_attr :formula def initialize properties={} super(properties) @@ -135,6 +146,7 @@ def create_params p[:units] = units if units p[:data_type] = self.class::DATA_CODES[data_type] if data_type p[:history] = history.to_i if history + p[:delta] = self.class::DELTA_CODES[delta] if delta p[:trends] = trends.to_i if trends p[:status] = self.class::STATUS_CODES[status] if status p[:delay] = frequency if frequency @@ -142,6 +154,10 @@ def create_params p[:multiplier] = 1 p[:formula] = multiply_by.to_f end + + if type == :calculated + p[:params] = formula + end end end @@ -153,7 +169,7 @@ def self.find_params options={} super().merge({ :filter => { :key_ => options[:key], - :id => options[:id] + :itemid => options[:id] } }.tap do |o| o[:hostids] = [options[:host_id]] if options[:host_id] @@ -171,13 +187,15 @@ def self.build item :value_type => VALUE_NAMES[item['value_type'].to_i], :data_type => DATA_NAMES[item['data_type'].to_i], :history => item['history'].to_i, + :delta => DELTA_NAMES[item['delta'].to_i], :trends => item['trends'].to_i, :status => STATUS_NAMES[item['status'].to_i], :application_ids => (item['applications'] || []).map { |app| app['applicationid'].to_i }, :key => item['key_'], :units => item['units'], :frequency => item['delay'].to_i, - :multiply_by => ((item['multiplier'].to_i == 1 && item['formula'].to_f != 0.0) ? item['formula'].to_f : nil) + :multiply_by => ((item['multiplier'].to_i == 1 && item['formula'].to_f != 0.0) ? item['formula'].to_f : nil), + :formula => item['params'] }) end From c5c55a4f7182cba6b4658c6a2911b7dc4be4901f Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Wed, 13 Mar 2013 16:09:54 +0400 Subject: [PATCH 30/32] Fix 2 bugs with screens, bump version --- VERSION | 2 +- lib/rubix/models/screen.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index b7a8bdf..5ca9ac6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.18 +0.5.19 diff --git a/lib/rubix/models/screen.rb b/lib/rubix/models/screen.rb index 74ef97f..ebf59ea 100644 --- a/lib/rubix/models/screen.rb +++ b/lib/rubix/models/screen.rb @@ -12,7 +12,7 @@ def initialize properties={} end zabbix_attr :name, :required => true - zabbix_attr :wsize, :default => 1 + zabbix_attr :vsize, :default => 1 zabbix_attr :hsize, :default => 1 # @@ -29,7 +29,7 @@ def validate def create_params { - :name => name, :hsize => hsize, :wsize => wsize, + :name => name, :hsize => hsize, :vsize => vsize, :screenitems => self.screen_items.map { |si| si.create_params } } end @@ -48,7 +48,7 @@ def self.build app params = { :id => app[id_field].to_i, :name => app['name'], - :screen_items => app['screenitems'].map { |si| ScreenItem.build si } + :screen_items => (app['screenitems'] || []).map { |si| ScreenItem.build si } } new(params) end From 95c5f6a4b8e499f49f229186e66f61e6dd985b67 Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Thu, 14 Mar 2013 13:48:20 +0400 Subject: [PATCH 31/32] Create GraphItem class --- VERSION | 2 +- lib/rubix/associations.rb | 1 + .../associations/has_many_graph_items.rb | 15 ++++ lib/rubix/models.rb | 1 + lib/rubix/models/graph.rb | 18 ++-- lib/rubix/models/graph_item.rb | 86 +++++++++++++++++++ spec/requests/graph_request_spec.rb | 2 + 7 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 lib/rubix/associations/has_many_graph_items.rb create mode 100644 lib/rubix/models/graph_item.rb diff --git a/VERSION b/VERSION index 5ca9ac6..5025832 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.19 +0.5.20 diff --git a/lib/rubix/associations.rb b/lib/rubix/associations.rb index 88b27f8..f4b478b 100644 --- a/lib/rubix/associations.rb +++ b/lib/rubix/associations.rb @@ -12,6 +12,7 @@ module Associations autoload :HasManyConditions, 'rubix/associations/has_many_conditions' autoload :HasManyInterfaces, 'rubix/associations/has_many_interfaces' autoload :HasManyScreenItems, 'rubix/associations/has_many_screen_items' + autoload :HasManyGraphItems, 'rubix/associations/has_many_graph_items' autoload :HasInventory, 'rubix/associations/has_inventory' autoload :HasMessage, 'rubix/associations/has_message' diff --git a/lib/rubix/associations/has_many_graph_items.rb b/lib/rubix/associations/has_many_graph_items.rb new file mode 100644 index 0000000..f2b8b28 --- /dev/null +++ b/lib/rubix/associations/has_many_graph_items.rb @@ -0,0 +1,15 @@ +module Rubix + module Associations + module HasManyGraphItems + + def graph_items= sis + @graph_items = sis + end + + def graph_items + @graph_items || [] + end + end + end +end + diff --git a/lib/rubix/models.rb b/lib/rubix/models.rb index 4c47322..5eeb5f8 100644 --- a/lib/rubix/models.rb +++ b/lib/rubix/models.rb @@ -19,6 +19,7 @@ module Rubix autoload :Interface, 'rubix/models/interface' autoload :Inventory, 'rubix/models/inventory' autoload :Graph, 'rubix/models/graph' + autoload :GraphItem, 'rubix/models/graph_item' autoload :Screen, 'rubix/models/screen' autoload :ScreenItem, 'rubix/models/screen_item' autoload :Message, 'rubix/models/message' diff --git a/lib/rubix/models/graph.rb b/lib/rubix/models/graph.rb index 15f4bac..2f20cba 100644 --- a/lib/rubix/models/graph.rb +++ b/lib/rubix/models/graph.rb @@ -1,17 +1,18 @@ module Rubix class Graph < Model + include Associations::HasManyGraphItems # # == Properties & Finding == # def initialize properties={} super(properties) + self.graph_items = properties[:graph_items].map { |gi| gi.is_a?(GraphItem) ? gi : GraphItem.new(gi) } if properties[:graph_items] end zabbix_attr :name, :required => true zabbix_attr :width, :required => true zabbix_attr :height, :required => true - zabbix_attr :graph_items # # == Validation = @@ -20,8 +21,8 @@ def initialize properties={} def validate raise ValidationError.new("A graph must have at least one graph item.") if graph_items.nil? || graph_items.empty? graph_items.each do |gi| - raise ValidationError.new("A graph item must have item_id property.") unless gi[:item_id] - raise ValidationError.new("A graph item must have color property.") unless gi[:color] + raise ValidationError.new("A graph item must have item_id property.") unless gi.item_id + raise ValidationError.new("A graph item must have color property.") unless gi.color end true end @@ -32,10 +33,9 @@ def validate def create_params { - :name => name, :height => height, :width => width - }.tap do |cp| - cp[:gitems] = graph_items.map { |gi| {:itemid => gi[:item_id], :color => gi[:color]}} - end + :name => name, :height => height, :width => width, + :gitems => self.graph_items.map { |gi| gi.create_params } + } end def update_params @@ -44,6 +44,7 @@ def update_params def self.find_params options={} super().merge({ + :selectGraphItems => 'extend', :filter => { :name => options[:name], id_field => options[:id] @@ -54,7 +55,8 @@ def self.find_params options={} def self.build app params = { :id => app[id_field].to_i, - :name => app['name'] + :name => app['name'], + :graph_items => (app['gitems'] || []).map { |id, gi| GraphItem.build gi } } new(params) end diff --git a/lib/rubix/models/graph_item.rb b/lib/rubix/models/graph_item.rb new file mode 100644 index 0000000..ec2fe75 --- /dev/null +++ b/lib/rubix/models/graph_item.rb @@ -0,0 +1,86 @@ +module Rubix + class GraphItem < Model + + def self.id_field + 'gitemid' + end + + zabbix_define :CALC_FUNC, { + :minimum => 1, + :average => 2, + :maximum => 4, + :last => 9 + } + + zabbix_define :DRAW_TYPE, { + :line => 0, + :region => 1, + :bold => 2, + :dot => 3, + :dashed => 4, + :gradient => 5 + } + + zabbix_define :Y_AXIS_SIDE, { + :left => 0, + :right => 1 + } + + # + # == Properties & Finding == + # + + def initialize properties={} + super(properties) + end + + zabbix_attr :color, :required => true + zabbix_attr :item_id, :required => true + zabbix_attr :calc_func, :default => :average + zabbix_attr :draw_type, :default => :line + zabbix_attr :graph_id + zabbix_attr :sort_order + zabbix_attr :type, :default => 0 + zabbix_attr :y_axis_side, :default => :left + + # + # == Validation = + # + + def validate + super + true + end + + # + # == Requests == + # + + def create_params + { + :color => color, + :itemid => item_id, + :calc_fnc => CALC_FUNC_CODES[calc_func], + :drawtype => DRAW_TYPE_CODES[draw_type], + :type => type, + :yaxisside => Y_AXIS_SIDE_CODES[y_axis_side] + } + end + + def self.build params + params = { + :id => params[id_field].to_i, + :color => params["color"], + :item_id => params["itemid"], + :calc_func => CALC_FUNC_NAMES[params["calc_fnc"].to_i], + :draw_type => DRAW_TYPE_NAMES[params["drawtype"].to_i], + :graph_id => params["graphid"], + :sort_order => params["sortorder"], + :type => params["type"], + :y_axis_side => Y_AXIS_SIDE_NAMES[params["yaxisside"].to_i] + } + new(params) + end + end +end + diff --git a/spec/requests/graph_request_spec.rb b/spec/requests/graph_request_spec.rb index 2597c70..4b7aafd 100644 --- a/spec/requests/graph_request_spec.rb +++ b/spec/requests/graph_request_spec.rb @@ -4,6 +4,8 @@ before do integration_test + Rubix.logger = Logger.new STDOUT + Rubix.logger.level = Logger::DEBUG @host_group = ensure_save(Rubix::HostGroup.new(:name => 'rubix_spec_host_group_1')) @host = ensure_save(Rubix::Host.new(:name => 'rubix_spec_host_1', :host_groups => [@host_group], :interfaces => ['ip' => '123.123.123.123', 'main' => 1])) @host = Rubix::Host.find(:id => @host.id) From ed612b498b0c4a366e878f60df3b7d5d35a3928c Mon Sep 17 00:00:00 2001 From: Ivan Evtukhovich Date: Fri, 15 Mar 2013 00:05:02 +0400 Subject: [PATCH 32/32] Fix bug with vsize in screen --- VERSION | 2 +- lib/rubix/connection.rb | 5 +++++ lib/rubix/models/model.rb | 3 ++- lib/rubix/models/screen.rb | 7 ++++--- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 5025832..72cb868 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.20 +0.5.21 diff --git a/lib/rubix/connection.rb b/lib/rubix/connection.rb index 6d1ec61..03da4c7 100644 --- a/lib/rubix/connection.rb +++ b/lib/rubix/connection.rb @@ -42,6 +42,9 @@ class Connection # @return [Rubix::Response] the last response from the Zabbix API -- useful for logging purposes attr_reader :last_response + # @return [Hash] the last request to the Zabbix API -- useful for debugging purposes + attr_reader :last_request + # Set up a connection to a Zabbix API. # # The +uri_or_string+ can be either a string or a URI @@ -74,6 +77,8 @@ def initialize uri_or_string, username=nil, password=nil # @return [Rubix::Response] def request method, params authorize! unless authorized? + @last_request = {:method => method, :params => params} + response = till_response do send_api_request :jsonrpc => "2.0", :id => request_id, diff --git a/lib/rubix/models/model.rb b/lib/rubix/models/model.rb index 5751fc0..63af76e 100644 --- a/lib/rubix/models/model.rb +++ b/lib/rubix/models/model.rb @@ -135,7 +135,8 @@ def save end def save! - raise Rubix::Error.new(Rubix.connection.last_response.body) unless save + raise Rubix::Error.new(Rubix.connection.last_response.body + "\n" + + Rubix.connection.last_request.inspect) unless save end # Validate this record. diff --git a/lib/rubix/models/screen.rb b/lib/rubix/models/screen.rb index ebf59ea..64e9f6e 100644 --- a/lib/rubix/models/screen.rb +++ b/lib/rubix/models/screen.rb @@ -46,12 +46,13 @@ def self.find_params options={} def self.build app params = { - :id => app[id_field].to_i, - :name => app['name'], + :id => app[id_field].to_i, + :name => app['name'], + :vsize => app['vsize'], + :hsize => app['hsize'], :screen_items => (app['screenitems'] || []).map { |si| ScreenItem.build si } } new(params) end end end -